Compare commits

...
Author SHA1 Message Date
Distiller ec4771b79a [0.72.0-rc.6] Bump version numbers 2023-06-13 19:39:32 +00:00
Lorenzo Sciandra a2df07ea2a [LOCAL] bump CLI to 11.3.2 2023-06-13 15:51:08 +01:00
Lorenzo Sciandra b2f273750b bumped packages versions
#publish-packages-to-npm
2023-06-13 15:50:05 +01:00
Gabriel Donadel 0817eaa301 Revert "fix: border width top/bottom not matching the border radius" (#37840)
Summary:
In an effort to fix https://github.com/facebook/react-native/issues/37753, this PR reverts the changes introduced by https://github.com/facebook/react-native/commit/cd6a91343ee24af83c7437b3f2449b41e97760e9 and https://github.com/facebook/react-native/commit/1d5103227851ab92de889d5e7e910393b5d8743a so border-radius width calculations work as expected

## Changelog:

[ANDROID] [FIXED] - Fix border-radius width calculations

Pull Request resolved: https://github.com/facebook/react-native/pull/37840

Test Plan:
Test border colors along with border-radius through RNTester
<img width="538" alt="image" src="https://github.com/facebook/react-native/assets/11707729/4b148d4b-35dc-4737-be00-c5ff156b0865">

Reviewed By: dmytrorykun

Differential Revision: D46684071

Pulled By: cipolleschi

fbshipit-source-id: cf7a80d0d63009b457f03d690b632e332a9b4a02
2023-06-13 15:49:11 +01:00
Nicola Corti 0da7e06f3f Remove CallInvoker parameter from toJs method in Codegen (#37832)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37832

This parameter is currently unused and is causing Android builds to fail
as they compile with `-Wall`

This is a follow-up to https://github.com/facebook/react-native/pull/37454/ as that PR updated only the `fromJs` and not the `toJs` method as well.

Changelog:
[Internal] [Changed] - Remove CallInvoker parameter from toJs method in Codegen

Reviewed By: rshest

Differential Revision: D46647110

fbshipit-source-id: 1f3e22aca7a3df11ac02b5c4b89c9311b8b1798c
2023-06-13 15:49:04 +01:00
Gabriel Donadel 2d15f50912 Fix Android border clip check (#37828)
Summary:
Instead of requiring all  types of border color values to be present we should only take into consideration the left, top, right, bottom, and allEdges values and inject block values into  colorBottom and colorTop.

This PR only addresses the first issue described here (https://github.com/facebook/react-native/issues/37753#issuecomment-1587196793) by kelset

## Changelog:

[ANDROID] [FIXED] - Fix border clip check

Pull Request resolved: https://github.com/facebook/react-native/pull/37828

Test Plan:
Test through rn-tester if border color is being applied

<img width="482" alt="image" src="https://github.com/facebook/react-native/assets/11707729/c8c8772c-da8d-4393-bc3f-5868eca5df15">

Reviewed By: lunaleaps

Differential Revision: D46643773

Pulled By: cipolleschi

fbshipit-source-id: efb1ea81bf2462c14767a2554880eb7c44989975
2023-06-13 15:48:58 +01:00
Gabriel Donadel 27600427a9 Fix loading NODE_BINARY inside Generate Legacy Components Interop (#37802)
Summary:
When trying to build an app using 0.72.0-RC.5 inside a project that uses `.xcode.env.local` the  `[CP-User] Generate Legacy Components Interop` Phase script fails to run due to a `Permission denied` error. That's because `.xcode.env.local` is not being loaded, resulting in `NODE_BINARY=" "` and then the `React-RCTAppDelegate` script tries to run `generate-legacy-interop-components.js` directly.

E.g

![image](https://github.com/facebook/react-native/assets/11707729/ce72d7d1-69ab-4477-a754-10cd52bb21a2)

In order to fix this we should run the `with-environment.sh` script instead of directly loading `.${PODS_ROOT}/../.xcode.env`

## Changelog:

[IOS] [FIXED] - Fix loading `NODE_BINARY` inside Generate Legacy Components Interop

Pull Request resolved: https://github.com/facebook/react-native/pull/37802

Test Plan: Make sure you don't have a `.xcode.env` file and run locally a project that uses React-RCTAppDelegate

Reviewed By: cortinico

Differential Revision: D46596246

Pulled By: cipolleschi

fbshipit-source-id: 5616395f39b0fae7b2fa9e59bd72c70f39198b4d
2023-06-13 15:48:51 +01:00
Alexander Eggers 8ed2cfded5 Add support for building with Xcode 15 (#37758)
Summary:
Fixes https://github.com/facebook/react-native/issues/37748

This PR adds a patch which fixes a build issue in Xcode 15.

## Changelog:

[IOS] [ADDED] - Add support for building with Xcode 15

Pull Request resolved: https://github.com/facebook/react-native/pull/37758

Reviewed By: cortinico

Differential Revision: D46524009

Pulled By: cipolleschi

fbshipit-source-id: 9f6c12e12a15c154467282a7b4a00e80e5cc0af2
2023-06-13 15:48:44 +01:00
Jakub Trzebiatowski 73f4a788f1 Fixed random styling for text nodes with many children (#36656)
Summary:
Attempting to fix the issue https://github.com/facebook/react-native/issues/33418

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[ANDROID] Fixed inconsistent styling for text nodes with many children

Pull Request resolved: https://github.com/facebook/react-native/pull/36656

Test Plan:
No test plan yet. I'd like to ask for help with creating one.

##

Putting template aside, I'd like to ask for a review of the approach I'm suggesting.

React Native as-is (at least in some cases) [messes up the styles](https://github.com/facebook/react-native/issues/33418#issuecomment-1485305556) for text nodes with more than 85 children, just like that.

![image](https://user-images.githubusercontent.com/2590174/227981778-7ef6e7e1-00ee-4f67-bcf1-d452183ea33d.png)

All of this text should be blue.

The root cause is that code (on Android) assumes it can assign as many `Spannable` span priority values as we'd like, while in reality, it has to be packed in an 8-bit-long section of the flags mask. So 255 possible values. In the scenario I produced, React generates three spans per text node, and for 85 text nodes, it sums up to 255. For each span, a new priority value is assigned.

As I understand it, we don't need that many priority values. If I'm not mistaken, these priorities are crucial only for ensuring that nested styles have precedence over the outer ones. I'm proposing to calculate the priority value "vertically" (based on the node's depth in the tree) not "horizontally" (based on its position).

It would be awesome if some core engineer familiar with `ReactAndroid` shared their experience with this module, especially if there are any known cases when we _know_ that we'd like to create overlapping spans fighting over the same aspects of the style.

Reviewed By: cortinico

Differential Revision: D46094200

Pulled By: NickGerleman

fbshipit-source-id: aae195c71684fe50469a1ee1bd30625cbfc3622f
2023-06-13 15:48:36 +01:00
Janic Duplessis dfc64d5bcc Fix copy / paste menu and simplify controlled text selection on Android (#37424)
Summary:
Currently when using a TextInput with a controlled selection prop the Copy / Paste menu is constantly getting dismissed and is impossible to use. This is because Android dismisses it when certain method that affect the input text are called (https://cs.android.com/android/platform/superproject/+/refs/heads/master:frameworks/base/core/java/android/widget/Editor.java;l=1667;drc=7346c436e5a11ce08f6a80dcfeb8ef941ca30176?q=Editor, https://cs.android.com/android/platform/superproject/+/refs/heads/master:frameworks/base/core/java/android/widget/TextView.java;l=6792;drc=7346c436e5a11ce08f6a80dcfeb8ef941ca30176). The solution to fix this is to avoid calling those methods when only the selection changes.

I also noticed there are a lot of differences on how selection is handled in old vs new arch and a lot of the selection handling can actually be removed as it is partially the cause of this issue.

This implements 2 mitigations to avoid the issue:

- Unify selection handling via commands for old arch, like fabric. Selection is currently a prop in the native component, but it is completely ignored in fabric and selection is set using commands. I removed the selection prop from the native component on Android so now it is exclusively handled with commands like it is currently for fabric. This makes it so that when the selection prop changes the native component no longer re-renders which helps mitigate this issue. More specifically for the old arch we no longer handle the `selection` prop in `ReactTextInputShadowNode`, which used to invalidate the shadow node and cause the text to be replaced and the copy / paste menu to close.

- Only set placeholder if the text value changed. Calling `EditText.setHint` also causes the copy / paste menu to be dismissed. Fabric will call all props handlers when a single prop changed, so if the `selection` prop changed the `placeholder` prop handler would be called too. To fix this we can check that the value changed before calling `setHint`.

## Changelog:

[ANDROID] [FIXED] - Fix copy / paste menu and simplify controlled text selection on Android

Pull Request resolved: https://github.com/facebook/react-native/pull/37424

Test Plan:
Tested on new and old arch in RNTester example.

Before:

https://github.com/facebook/react-native/assets/2677334/a915b62a-dd79-4adb-9d95-2317780431cf

After:

https://github.com/facebook/react-native/assets/2677334/0dd475ed-8981-410c-8908-f00998dcc425

Reviewed By: cortinico

Differential Revision: D45958425

Pulled By: NickGerleman

fbshipit-source-id: 7b90c1270274f6621303efa60b5398b1a49276ca

# Conflicts:
#	packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java
2023-06-13 15:48:22 +01:00
Lorenzo Sciandra bab5babc98 [LOCAL] bump hermes podlock 2023-06-06 10:13:53 +01:00
Distiller a98c7c6f54 [0.72.0-rc.5] Bump version numbers 2023-06-01 09:35:34 +00:00
fortmarek 7dc11bc468 bumped packages versions
#publish-packages-to-npm
2023-06-01 09:22:51 +02:00
Distiller e11396e998 [0.72.0-rc.4] Bump version numbers 2023-05-31 07:15:26 +00:00
Riccardo Cipolleschi 60a452b485 [LOCAL] Fix performance issues in Hermes when Debug 2023-05-30 11:44:26 +01:00
Riccardo CipolleschiandRiccardo Cipolleschi 32327cc177 [LOCAL] Fix hermesc for linux (#37591)
Co-authored-by: Riccardo Cipolleschi <cipolleschi@fb.com>
2023-05-26 13:52:21 +01:00
Nicola Corti 52d2065910 [LOCAL] Make sure Java Toolchain and source/target level is applied to all projects (#37576) 2023-05-26 12:31:11 +01:00
Riccardo Cipolleschi e0c88fed2d [LOCAL] Fix Ruby tests 2023-05-26 11:02:50 +01:00
Riccardo Cipolleschi a4aaee0c5e [LOCAL] Remove double definition of task wrapper after merge conflict 2023-05-26 10:32:35 +01:00
Riccardo Cipolleschi 74e3803e4c bumped packages versions
#publish-packages-to-npm
2023-05-26 10:28:49 +01:00
Riccardo Cipolleschi 7c5dc1d9bc [LOCAL] bump metro to 0.76.5 and CLI to 11.3.1 2023-05-26 10:27:56 +01:00
Samuel Susla c43bd7a73a Do not use setNativeState in RuntimeScheduler::Task
Summary:
changelog: [internal]

`setNativeState` is not implemented in JSC. Let's stick to host objects for now.

Reviewed By: cipolleschi

Differential Revision: D46193786

fbshipit-source-id: 9d36801bb9faa5c144a461bcbe623762bf6947b1
2023-05-26 10:14:45 +01:00
Riccardo Cipolleschi dc6a2c384d [LOCAL] Do not use NativeState as JSC does not implement it 2023-05-25 18:17:41 +01:00
Riccardo Cipolleschi ee177cab75 [LOCAL] Remove conformance to RCTComponentViewFactoryComponentProvider which does not exists in 0.72 2023-05-25 17:34:17 +01:00
Samuel Susla dd9a5ab8a9 Enable RuntimeScheduler in old architecture (#37523)
Summary:

[IOS] [FIXED] - unexpected useEffects flushing semantics

Pull Request resolved: https://github.com/facebook/react-native/pull/37523

Test Plan: Run RNTester with old architecture and make sure RuntimeScheduler is used.

Reviewed By: cipolleschi

Differential Revision: D46078324

Pulled By: sammy-SC

fbshipit-source-id: 5f18cbe60e6c9c753c373f175ba413b79288a928
2023-05-25 17:17:35 +01:00
Frank Calise 00027a5ca9 chore(Podfile): fixed URL to New Arch info (#37535)
Summary:
I was following the upgrade helper from [0.71.7 -> 0.72.0-rc.3](https://react-native-community.github.io/upgrade-helper/?from=0.71.7&to=0.72.0-rc.3) and came across a comment with a URL in the Podfile changes. That comment lead to a 404, so this updates that to the correct URL.

Confirmed this was an issue on the [Roadmap to 0.72.0](https://github.com/reactwg/react-native-releases/discussions/54#discussioncomment-5976797)

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[IOS] [CHANGED] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[IOS] [CHANGED] - fixed URL to New Arch info

Pull Request resolved: https://github.com/facebook/react-native/pull/37535

Test Plan: Only updated a comment, no code changes

Reviewed By: cortinico

Differential Revision: D46145428

Pulled By: cipolleschi

fbshipit-source-id: 600274222725567e1cbae041a3dac9561da15aff
2023-05-25 16:36:48 +01:00
Rob Hogan 072b7f7b86 Use Content-Location header in bundle response as JS source URL (#37501)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37501

This is the iOS side of the fix for https://github.com/facebook/react-native/issues/36794.

That issue aside for the moment, the high-level idea here is to conceptually separate the bundle *request URL*, which represents a request for the *latest* bundle, from the *source URL* passed to JS engines, which should represent the code actually being executed. In future, we'd like to use this to refer to a point-in-time snapshot of the bundle, so that stack traces more often refer to the code that was actually run, even if it's since been updated on disk (actually implementing this isn't planned at the moment, but it helps describe the distinction).

Short term, this separation gives us a way to address the issue with JSC on iOS 16.4 by allowing Metro to provide the client with a [JSC-safe URL](https://github.com/react-native-community/discussions-and-proposals/pull/646) to pass to the JS engine, even where the request URL isn't JSC-safe.

We'll deliver that URL to the client on HTTP bundle requests via the [`Content-Location`](https://www.rfc-editor.org/rfc/rfc9110#name-content-location) header, which is a published standard for communicating a location for the content provided in a successful response (typically used to provide a direct URL to an asset after content negotiation, but I think it fits here too).

For the long-term goal we should follow up with the same functionality on Android and out-of-tree platforms, but it's non-essential for anything other than iOS 16.4 at the moment.

For the issue fix to work end-to-end we'll also need to update Metro, but the two pieces are decoupled and non-breaking so it doesn't matter which lands first.

Changelog:
[iOS][Changed] Prefer `Content-Location` header in bundle response as JS source URL

Reviewed By: huntie

Differential Revision: D45950661

fbshipit-source-id: 170fcd63a098f81bdcba55ebde0cf3569dceb88d
2023-05-25 16:36:41 +01:00
Tommy Nguyen a168f4bbcb fix: limit diagnostics width output by hermesc (#37531)
Summary:
Limit diagnostics width output by `hermesc` as they may cause slowdowns or even crashes in Gradle/Xcode when a minified bundle is used as input. This occurs because Hermes is unable to determine the terminal width when executed by Gradle/Xcode, and falls back to "unlimited". If the input is a minified bundle, Hermes will output the whole bundle for each warning.

See issues filed:
- https://github.com/microsoft/rnx-kit/issues/2416
- https://github.com/microsoft/rnx-kit/issues/2419
- https://github.com/microsoft/rnx-kit/issues/2424

## Changelog:

[GENERAL] [FIXED] - Limit diagnostics width output by `hermesc`

Pull Request resolved: https://github.com/facebook/react-native/pull/37531

Test Plan: See listed issues for repros.

Reviewed By: cipolleschi

Differential Revision: D46102686

Pulled By: cortinico

fbshipit-source-id: 1b821cad7ef0d561a5e1c13a7aedf9b10164620a
2023-05-25 16:36:31 +01:00
Riccardo Cipolleschi ad965a1a0d Make CircleCI caches for hermesc be version dependent (#37452)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37452

Fixes #37428

We do have cache poisoning for hermesc on Windows and Linux due to reusing the same cache key among different
React Native version. This fixes it by specifying a cache key which is version dependent + it invalidates the
caches by defining a new key.

Changelog:
[Internal] [Fixed] - Make CircleCI caches for hermesc be version dependent

Reviewed By: cortinico

Differential Revision: D45909178

fbshipit-source-id: 830c87ae45739c7053342a68dac2ee7581945c1d

# Conflicts:
#	.circleci/config.yml
2023-05-25 16:33:36 +01:00
Nicola Corti 47b45df65c Make sure the Native RuntimeScheduler is initialized on Old Arch (#37517)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37517

Fixes #35778

We got reports of regressions on `useEffect` starting from 0.69+ when on Hermes.

The issue seems to be caused by a bump of the `scheduler` package from 0.20 to 0.21.
In scheduler@0.21, the method `setImmediate` gets called if available
(see https://github.com/facebook/react/pull/20834). This causes React Native to use Microtasks
which ends up in changing the semantic of useEffect.

The solution is to use the Native RuntimeScheduler properly.
On Paper specifically, we never initialized it as it's effectively initialized by the
TurboModuleManagerDelegate. Here I trigger the initialization of it on Paper as well.

Changelog:
[Android] [Fixed] - Make sure the Native RuntimeScheduler is initialized on Old Arch

Reviewed By: sammy-SC

Differential Revision: D46024807

fbshipit-source-id: d72cd774df58410467644cddeaaf37e3c227b505
2023-05-25 16:31:54 +01:00
Nicola Corti cddcf09255 Add -Wno-error=cpp on App's default Cmake file (#37516)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37516

This will fail build failures from apps which are using libraries which imports
```
#include <react/renderer/graphics/conversions.h>
```
That's just a warning but our usage of `-Wall -Werror` is causing this to fail user builds.

More context on this issue here:
https://github.com/reactwg/react-native-releases/discussions/54#discussioncomment-5968545

We can revert this `-Wno-error` once we're on 0.73 as that specific #warning will be entirely
removed from the codebase.

Changelog:
[Internal] [Changed] - Add -Wno-error=cpp on App's default Cmake file

Reviewed By: dmytrorykun

Differential Revision: D46071400

fbshipit-source-id: 4937fb1255df3f2765f645dfd59f5c58526dee42
2023-05-25 16:31:47 +01:00
Nicola Corti 5e847c4309 [LOCAL] Remove license header from android/app/build.gradle (#37514) 2023-05-22 15:32:54 +01:00
Lorenzo Sciandra 451a599fa1 bumped packages versions
#publish-packages-to-npm
2023-05-22 12:20:47 +01:00
Lorenzo Sciandra be9941223e [LOCAL] update podlock file 2023-05-22 12:19:44 +01:00
Lorenzo Sciandra f942f2183e [LOCAL] yarn lock wasn't updated during the CLI bump 2023-05-22 12:16:00 +01:00
Douglas Lowder a86a54e7ed fix: [gradle-plugin] 3rd party lib dependency substitution (#37445)
Summary:
For 3rd party libraries to work with a React Native fork (such as the TV repo) that uses a different Maven group for `react-android` and `hermes-android` artifacts, an additional dependency substitution is required.

## Changelog:

[Android][fixed] RNGP dependency substitutions for fork with different Maven group

Pull Request resolved: https://github.com/facebook/react-native/pull/37445

Test Plan:
- Manual tested with an existing project
- Unit tests pass

Reviewed By: rshest, dmytrorykun

Differential Revision: D45948901

Pulled By: cortinico

fbshipit-source-id: 4151a1d3616172a92c68812c3a0034c98b330d67
2023-05-22 12:14:31 +01:00
Nicola Corti 472012dd04 Make sure the -DANDROID compilation flag is always included. (#37451)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37451

It seems like starting from AGP 7.4, Android is not including the `-DANDROID` flag
anymore from the NDK toolchain.

As we do have several `#ifdef` logic that takes care of having this macro set,
I'm going to make sure it's always set for both ReactAndroid, hermes-engine
and the template.

Changelog:
[Android] [Fixed] - Make sure the -DANDROID compilation flag is always included

Reviewed By: javache

Differential Revision: D45908787

fbshipit-source-id: 07284712d7bcce73dc8ea0dffd4a9d00af4de1d2
2023-05-22 12:14:24 +01:00
Christoph Purrer a3b4428cad Remove unused jsInvoker from Cxx TM enums (#37454)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37454

Raised here: https://github.com/reactwg/react-native-releases/discussions/54#discussioncomment-5914928

Changelog: [Internal]

Reviewed By: rshest

Differential Revision: D45918922

fbshipit-source-id: 931d2017c37e7327ba472c36e3ac0b29b74d093d
2023-05-22 12:14:17 +01:00
Nicola Corti d880c04e7a Remove deprecated POST_NOTIFICATION from PermissionsAndroid (#36936)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36936

I'm removing `POST_NOTIFICATION` as that's a typo as it should be `POST_NOTIFICATIONS`
We had both in version 0.71 so we can remove the wrong one as it's misleading for users.

Changelog:
[Android] [Removed] - Remove deprecated POST_NOTIFICATION from `PermissionsAndroid`

Reviewed By: sshic

Differential Revision: D45054310

fbshipit-source-id: be733811a1ee8e7c9d6e4986c0303eed7c07c35b
2023-05-22 12:14:10 +01:00
Kyle Roach 43ff1c42dc fix(types): cross platform autoComplete for TextInput (#36931)
Summary:
Since v0.71 the autoComplete prop on TextInput is available on iOS ([release notes](https://reactnative.dev/blog/2023/01/12/version-071#component-specific-behavior)). However, this change is not reflected in the types.

Original types PR here - https://github.com/DefinitelyTyped/DefinitelyTyped/pull/65144 by chwallen

## Changelog:

[GENERAL] [FIXED] - Fix autoComplete type for TextInput

Pull Request resolved: https://github.com/facebook/react-native/pull/36931

Test Plan: Setting the autoComplete prop on TextInput to `nickname`, `organization`, `organization-title`, or `url` should not result in typescript errors.

Reviewed By: NickGerleman

Differential Revision: D45052350

Pulled By: javache

fbshipit-source-id: 40993833b4ed14f91e3bf3521a264ea93517a0c9
2023-05-22 12:14:02 +01:00
Pranav Yadav 9476eb6cdc Bump CLI to v11.3.0 in 0.72-stable (#37467) 2023-05-22 11:57:34 +01:00
Ruslan Lesiutin 97986561f6 backporting babel bumps to 0.72 (#37492) 2023-05-22 11:57:11 +01:00
Lorenzo Sciandra 42fc885350 Merge pull request #37258 from bang9/cherrypick-0.72-fix-virtualized-list-for-mvcp 2023-05-22 11:56:46 +01:00
Lorenzo Sciandra 614d9f88e3 Merge pull request #37403 from lunaleaps/add-experimental-types 2023-05-22 11:56:22 +01:00
Luna Wei 8c4694f708 Remove inline props from experimental 2023-05-11 23:02:25 -07:00
Luna Wei 014ea40012 Make the fabric-only CSS aliases experimental (#37338)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37338

Changelog: [General] [Changed] - Change the way types for New Architecture/experimental APIs are exposed.

Reviewed By: NickGerleman

Differential Revision: D45699522

fbshipit-source-id: 9265ce0c0964bf2e967624cb4d81c2c8a58cfbe7
2023-05-11 22:59:09 -07:00
Janic Duplessis 96d7c92a06 Fix VirtualizedList with maintainVisibleContentPosition (#35993)
Summary:
`maintainVisibleContentPosition` is broken when using virtualization and the new content pushes visible content outside its "window". This can be reproduced in the example from this diff. When using a large page size it will always push visible content outside of the list "window" which will cause currently visible views to be unmounted so the implementation of `maintainVisibleContentPosition` can't adjust the content inset since the visible views no longer exist.

The first illustration shows the working case, when the new content doesn't push visible content outside the window. The red box represents the window, all views outside the box are not mounted, which means the native implementation of `maintainVisibleContentPosition`  has no way to know it exists. In that case the first visible view is https://github.com/facebook/react-native/issues/2, after new content is added https://github.com/facebook/react-native/issues/2 is still inside the window so there's not problem adjusting content offset to maintain position. As you can see Step 1 and 3 result in the same position for all initial views.

The second illustation shows the broken case, when new content is added and pushes the first visible view outside the window. As you can see in step 2 the view https://github.com/facebook/react-native/issues/2 is no longer rendered so there's no way to maintain its position.

#### Illustration 1

![image](https://user-images.githubusercontent.com/2677334/163263472-eaf7342a-9b94-4c49-9a34-17bf8ef4ffb9.png)

#### Illustration 2

![image](https://user-images.githubusercontent.com/2677334/163263528-a8172341-137e-417e-a0c7-929d1e4e6791.png)

To fix `maintainVisibleContentPosition` when using `VirtualizedList` we need to make sure the visible items stay rendered when new items are added at the start of the list.

In order to do that we need to do the following:

- Detect new items that will cause content to be adjusted
- Add cells to render mask so that previously visible cells stay rendered
- Ignore certain updates while scroll metrics are invalid

### Detect new items that will cause content to be adjusted

The goal here is to know that scroll position will be updated natively by the `maintainVisibleContentPosition` implementation. The problem is that the native code uses layout heuristics which are not easily available to JS to do so. In order to approximate the native heuristic we can assume that if new items are added at the start of the list, it will cause `maintainVisibleContentPosition` to be triggered. This simplifies JS logic a lot as we don't have to track visible items. In the worst case if for some reason our JS heuristic is wrong, it will cause extra cells to be rendered until the next scroll event, or content position will not be maintained (what happens all the time currently). I think this is a good compromise between complexity and accuracy.

We need to find how many items have been added before the first one. To do that we save the key of the first item in state `firstItemKey`. When data changes we can find the index of `firstItemKey` in the new data and that will be the amount we need to adjust the window state by.

Note that this means that keys need to be stable, and using index won't work.

### Add cells to render mask so that previously visible cells stay rendered

Once we have the adjusted number we can save this in a new state value `maintainVisibleContentPositionAdjustment` and add the adjusted cells to the render mask.

This state is then cleared when we receive updated scroll metrics, once the native implementation is done adding the new items and adjusting the content offset.

This value is also only set when `maintainVisibleContentPosition` is set so this makes sure this maintains the currently behavior when that prop is not set.

### Ignore certain updates while scroll metrics are invalid

While the `maintainVisibleContentPositionAdjustment` state is set we know that the current scroll metrics are invalid since they will be updated in the native `ScrollView` implementation. In that case we want to prevent certain code from running.

One example is `onStartReached` that will be called incorrectly while we are waiting for updated scroll metrics.

## Changelog

[General] [Fixed] - Fix VirtualizedList with maintainVisibleContentPosition

Pull Request resolved: https://github.com/facebook/react-native/pull/35993

Test Plan:
Added bidirectional paging to RN tester FlatList example. Note that for this to work RN tester need to be run using old architecture on iOS, to use new architecture it requires https://github.com/facebook/react-native/pull/35319

Using debug mode we can see that virtualization is still working properly, and content position is being maintained.

https://user-images.githubusercontent.com/2677334/163294404-e2eeae5b-e079-4dba-8664-ad280c171ae6.mov

Reviewed By: yungsters

Differential Revision: D45294060

Pulled By: NickGerleman

fbshipit-source-id: 8e5228318886aa75da6ae397f74d1801d40295e8
2023-05-05 03:24:18 +09:00
Oskar Kwaśniewski acc5fdff47 fix: make sure initialScrollIndex is bigger than 0 (#36844)
Summary:
Hey,

`adjustCellsAroundViewport` function was checking if `props.initialScrollIndex` is truthy and -1 was returning true. This caused bugs with rendering for tvOS: https://github.com/react-native-tvos/react-native-tvos/pull/485 There are warnings in the code about `initalScrollIndex` being smaller than 0 but this if statement would still allow that.

## Changelog:

[General] [Fixed] - Make sure initialScrollToIndex is bigger than 0 when adjusting cells

Pull Request resolved: https://github.com/facebook/react-native/pull/36844

Test Plan: Pass -1 as initialScrollToIndex. Check that this code is executed.

Reviewed By: cipolleschi

Differential Revision: D44856266

Pulled By: NickGerleman

fbshipit-source-id: 781a1c0efeae93f00766eede4a42559dcd066d7d
2023-05-05 03:23:36 +09:00
100 changed files with 3506 additions and 1769 deletions
+27 -8
View File
@@ -62,7 +62,8 @@ references:
hermes_workspace_cache_key: &hermes_workspace_cache_key v4-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "/tmp/hermes/hermesversion" }}
hermes_workspace_debug_cache_key: &hermes_workspace_debug_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-debug-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_workspace_release_cache_key: &hermes_workspace_release_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-release-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_windows_cache_key: &hermes_windows_cache_key v3-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "tmp/hermes/hermesversion" }}
hermes_linux_cache_key: &hermes_linux_cache_key v1-hermes-{{ .Environment.CIRCLE_JOB }}-linux-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_windows_cache_key: &hermes_windows_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-windows-{{ checksum "/Users/circleci/project/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_tarball_debug_cache_key: &hermes_tarball_debug_cache_key v4-hermes-tarball-debug-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
hermes_tarball_release_cache_key: &hermes_tarball_release_cache_key v3-hermes-tarball-release-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}
pods_cache_key: &pods_cache_key v8-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }}
@@ -314,11 +315,24 @@ commands:
- run:
name: Get React Native version
command: |
VERSION=$( grep '"version"' packages/react-native/package.json | cut -d '"' -f 4 | head -1)
VERSION=$(cat packages/react-native/package.json | jq -r '.version')
# Save the react native version we are building in a file so we can use that file as part of the cache key.
echo "$VERSION" > /tmp/react-native-version
echo "React Native Version is $(cat /tmp/react-native-version)"
echo "Hermes commit is $(cat /tmp/hermes/hermesversion)"
HERMES_VERSION="$(cat /tmp/hermes/hermesversion)"
echo "Hermes commit is $HERMES_VERSION"
get_react_native_version_windows:
steps:
- run:
name: Get React Native version on Windows
command: |
$VERSION=cat packages/react-native/package.json | jq -r '.version'
# Save the react native version we are building in a file so we can use that file as part of the cache key.
echo "$VERSION" > /tmp/react-native-version
echo "React Native Version is $(cat /tmp/react-native-version)"
$HERMES_VERSION=cat C:\Users\circleci\project\tmp\hermes\hermesversion
echo "Hermes commit is $HERMES_VERSION"
with_hermes_tarball_cache_span:
parameters:
@@ -1121,7 +1135,7 @@ jobs:
- image: debian:11
environment:
- HERMES_WS_DIR: *hermes_workspace_root
- HERMES_VERSION_FILE: "sdks/.hermesversion"
- HERMES_VERSION_FILE: "packages/react-native/sdks/.hermesversion"
- BUILD_FROM_SOURCE: true
steps:
- run:
@@ -1140,8 +1154,10 @@ jobs:
mkdir -p "/tmp/hermes" "/tmp/hermes/download" "/tmp/hermes/hermes"
if [ -f "$HERMES_VERSION_FILE" ]; then
echo "Hermes version file found. Using the latest commit"
cat $HERMES_VERSION_FILE > /tmp/hermes/hermesversion
else
echo "No hermes version file found. Using the latest commit"
HERMES_TAG_SHA=$(git ls-remote https://github.com/facebook/hermes main | cut -f 1 | tr -d '[:space:]')
echo $HERMES_TAG_SHA > /tmp/hermes/hermesversion
fi
@@ -1172,17 +1188,18 @@ jobs:
docker:
- image: debian:bullseye
resource_class: "xlarge"
working_directory: /root
steps:
- checkout_code_with_cache
- run:
name: Install dependencies
command: |
apt update
apt install -y git openssh-client cmake build-essential \
libreadline-dev libicu-dev zip python3
libreadline-dev libicu-dev jq zip python3
- *attach_hermes_workspace
- get_react_native_version
- restore_cache:
key: *hermes_workspace_cache_key
key: *hermes_linux_cache_key
- run:
name: Set up workspace
command: |
@@ -1201,7 +1218,7 @@ jobs:
cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/.
fi
- save_cache:
key: *hermes_workspace_cache_key
key: *hermes_linux_cache_key
paths:
- /tmp/hermes/linux64-bin/
- /tmp/hermes/hermes/destroot/
@@ -1322,7 +1339,9 @@ jobs:
- MSBUILD_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin'
- CMAKE_DIR: 'C:\Program Files\CMake\bin'
steps:
- checkout_code_with_cache
- *attach_hermes_workspace
- get_react_native_version_windows
- restore_cache:
key: *hermes_windows_cache_key
- run:
+4 -4
View File
@@ -3,7 +3,7 @@ GEM
specs:
CFPropertyList (3.0.6)
rexml
activesupport (7.0.4.3)
activesupport (7.0.5)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
@@ -62,7 +62,7 @@ GEM
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
httpclient (2.8.3)
i18n (1.13.0)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
json (2.6.3)
minitest (5.18.0)
@@ -93,7 +93,7 @@ DEPENDENCIES
cocoapods (~> 1.12)
RUBY VERSION
ruby 3.0.5p211
ruby 3.0.6p216
BUNDLED WITH
2.4.10
2.4.13
+6 -6
View File
@@ -50,13 +50,13 @@
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/eslint-parser": "^7.19.0",
"@babel/eslint-parser": "^7.20.0",
"@babel/generator": "^7.20.0",
"@babel/plugin-transform-regenerator": "^7.0.0",
"@babel/plugin-transform-regenerator": "^7.20.0",
"@definitelytyped/dtslint": "^0.0.127",
"@jest/create-cache-key-function": "^29.2.1",
"@reactions/component": "^2.0.2",
"@react-native/metro-config": "^0.72.5",
"@react-native/metro-config": "^0.72.6",
"@types/react": "^18.0.18",
"@typescript-eslint/parser": "^5.30.5",
"async": "^3.2.2",
@@ -84,9 +84,9 @@
"jest": "^29.2.1",
"jest-junit": "^10.0.0",
"jscodeshift": "^0.14.0",
"metro-babel-register": "0.76.4",
"metro-memory-fs": "0.76.4",
"metro-react-native-babel-transformer": "0.76.4",
"metro-babel-register": "0.76.5",
"metro-memory-fs": "0.76.5",
"metro-react-native-babel-transformer": "0.76.5",
"mkdirp": "^0.5.1",
"mock-fs": "^5.1.4",
"prettier": "^2.4.1",
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-config",
"version": "0.72.1",
"version": "0.72.2",
"description": "ESLint config for React Native",
"main": "index.js",
"license": "MIT",
@@ -12,7 +12,7 @@
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/eslint-config-react-native-community#readme",
"dependencies": {
"@babel/core": "^7.20.0",
"@babel/eslint-parser": "^7.19.0",
"@babel/eslint-parser": "^7.20.0",
"@react-native/eslint-plugin": "^0.72.0",
"@typescript-eslint/eslint-plugin": "^5.30.5",
"@typescript-eslint/parser": "^5.30.5",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-plugin-specs",
"version": "0.72.3",
"version": "0.72.4",
"description": "ESLint rules to validate NativeModule and Component Specs",
"main": "index.js",
"repository": {
@@ -14,11 +14,11 @@
},
"dependencies": {
"@babel/core": "^7.20.0",
"@babel/eslint-parser": "^7.19.0",
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
"@babel/preset-flow": "^7.18.0",
"@babel/eslint-parser": "^7.20.0",
"@babel/plugin-transform-flow-strip-types": "^7.20.0",
"@babel/preset-flow": "^7.20.0",
"@react-native/codegen": "*",
"flow-parser": "^0.185.0",
"flow-parser": "^0.206.0",
"make-dir": "^2.1.0",
"pirates": "^4.0.1",
"source-map-support": "0.5.0"
@@ -17,10 +17,10 @@
"yargs": "^17.6.2"
},
"devDependencies": {
"@babel/cli": "^7.19.0",
"@babel/cli": "^7.20.0",
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/preset-flow": "^7.18.0",
"@babel/preset-flow": "^7.20.0",
"jest": "^29.2.1"
},
"jest": {
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/metro-config",
"version": "0.72.5",
"version": "0.72.6",
"description": "Metro configuration for React Native.",
"repository": {
"type": "git",
@@ -11,8 +11,8 @@
"exports": "./index.js",
"dependencies": {
"@react-native/js-polyfills": "^0.72.1",
"metro-config": "0.76.4",
"metro-react-native-babel-transformer": "0.76.4",
"metro-runtime": "0.76.4"
"metro-config": "0.76.5",
"metro-react-native-babel-transformer": "0.76.5",
"metro-runtime": "0.76.5"
}
}
@@ -193,7 +193,7 @@ enum NativeEnumTurboModuleStatusRegularEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusRegularEnum> {
static NativeEnumTurboModuleStatusRegularEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusRegularEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"Active\\") {
return NativeEnumTurboModuleStatusRegularEnum::Active;
@@ -206,7 +206,7 @@ struct Bridging<NativeEnumTurboModuleStatusRegularEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusRegularEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusRegularEnum value) {
if (value == NativeEnumTurboModuleStatusRegularEnum::Active) {
return bridging::toJs(rt, \\"Active\\");
} else if (value == NativeEnumTurboModuleStatusRegularEnum::Paused) {
@@ -225,7 +225,7 @@ enum NativeEnumTurboModuleStatusStrEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusStrEnum> {
static NativeEnumTurboModuleStatusStrEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusStrEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"active\\") {
return NativeEnumTurboModuleStatusStrEnum::Active;
@@ -238,7 +238,7 @@ struct Bridging<NativeEnumTurboModuleStatusStrEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusStrEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusStrEnum value) {
if (value == NativeEnumTurboModuleStatusStrEnum::Active) {
return bridging::toJs(rt, \\"active\\");
} else if (value == NativeEnumTurboModuleStatusStrEnum::Paused) {
@@ -257,7 +257,7 @@ enum NativeEnumTurboModuleStatusNumEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusNumEnum> {
static NativeEnumTurboModuleStatusNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 2) {
return NativeEnumTurboModuleStatusNumEnum::Active;
@@ -270,7 +270,7 @@ struct Bridging<NativeEnumTurboModuleStatusNumEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusNumEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusNumEnum value) {
if (value == NativeEnumTurboModuleStatusNumEnum::Active) {
return bridging::toJs(rt, 2);
} else if (value == NativeEnumTurboModuleStatusNumEnum::Paused) {
@@ -289,7 +289,7 @@ enum NativeEnumTurboModuleStatusFractionEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusFractionEnum> {
static NativeEnumTurboModuleStatusFractionEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusFractionEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 0.2f) {
return NativeEnumTurboModuleStatusFractionEnum::Active;
@@ -302,7 +302,7 @@ struct Bridging<NativeEnumTurboModuleStatusFractionEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusFractionEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusFractionEnum value) {
if (value == NativeEnumTurboModuleStatusFractionEnum::Active) {
return bridging::toJs(rt, 0.2f);
} else if (value == NativeEnumTurboModuleStatusFractionEnum::Paused) {
@@ -2136,7 +2136,7 @@ enum NativeEnumTurboModuleStatusRegularEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusRegularEnum> {
static NativeEnumTurboModuleStatusRegularEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusRegularEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"Active\\") {
return NativeEnumTurboModuleStatusRegularEnum::Active;
@@ -2149,7 +2149,7 @@ struct Bridging<NativeEnumTurboModuleStatusRegularEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusRegularEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusRegularEnum value) {
if (value == NativeEnumTurboModuleStatusRegularEnum::Active) {
return bridging::toJs(rt, \\"Active\\");
} else if (value == NativeEnumTurboModuleStatusRegularEnum::Paused) {
@@ -2168,7 +2168,7 @@ enum NativeEnumTurboModuleStatusStrEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusStrEnum> {
static NativeEnumTurboModuleStatusStrEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusStrEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"active\\") {
return NativeEnumTurboModuleStatusStrEnum::Active;
@@ -2181,7 +2181,7 @@ struct Bridging<NativeEnumTurboModuleStatusStrEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusStrEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusStrEnum value) {
if (value == NativeEnumTurboModuleStatusStrEnum::Active) {
return bridging::toJs(rt, \\"active\\");
} else if (value == NativeEnumTurboModuleStatusStrEnum::Paused) {
@@ -2200,7 +2200,7 @@ enum NativeEnumTurboModuleStatusNumEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusNumEnum> {
static NativeEnumTurboModuleStatusNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 2) {
return NativeEnumTurboModuleStatusNumEnum::Active;
@@ -2213,7 +2213,7 @@ struct Bridging<NativeEnumTurboModuleStatusNumEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusNumEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusNumEnum value) {
if (value == NativeEnumTurboModuleStatusNumEnum::Active) {
return bridging::toJs(rt, 2);
} else if (value == NativeEnumTurboModuleStatusNumEnum::Paused) {
@@ -2232,7 +2232,7 @@ enum NativeEnumTurboModuleStatusFractionEnum { Active, Paused, Off };
template <>
struct Bridging<NativeEnumTurboModuleStatusFractionEnum> {
static NativeEnumTurboModuleStatusFractionEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static NativeEnumTurboModuleStatusFractionEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 0.2f) {
return NativeEnumTurboModuleStatusFractionEnum::Active;
@@ -2245,7 +2245,7 @@ struct Bridging<NativeEnumTurboModuleStatusFractionEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusFractionEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusFractionEnum value) {
if (value == NativeEnumTurboModuleStatusFractionEnum::Active) {
return bridging::toJs(rt, 0.2f);
} else if (value == NativeEnumTurboModuleStatusFractionEnum::Paused) {
+11 -11
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/codegen",
"version": "0.72.4",
"version": "0.72.6",
"description": "⚛️ Code generation tools for React Native",
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-codegen",
"repository": {
@@ -19,21 +19,21 @@
],
"dependencies": {
"@babel/parser": "^7.20.0",
"flow-parser": "^0.185.0",
"flow-parser": "^0.206.0",
"jscodeshift": "^0.14.0",
"nullthrows": "^1.1.1"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-transform-async-to-generator": "^7.0.0",
"@babel/plugin-transform-destructuring": "^7.0.0",
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
"@babel/preset-env": "^7.14.0",
"@babel/plugin-proposal-class-properties": "^7.18.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.0",
"@babel/plugin-proposal-object-rest-spread": "^7.20.0",
"@babel/plugin-proposal-optional-chaining": "^7.20.0",
"@babel/plugin-syntax-dynamic-import": "^7.8.0",
"@babel/plugin-transform-async-to-generator": "^7.20.0",
"@babel/plugin-transform-destructuring": "^7.20.0",
"@babel/plugin-transform-flow-strip-types": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"chalk": "^4.0.0",
"glob": "^7.1.1",
"invariant": "^2.2.4",
@@ -338,12 +338,12 @@ enum ${enumName} { ${values} };
template <>
struct Bridging<${enumName}> {
static ${enumName} fromJs(jsi::Runtime &rt, ${fromValue}, const std::shared_ptr<CallInvoker> &jsInvoker) {
static ${enumName} fromJs(jsi::Runtime &rt, ${fromValue}) {
${fromValueConversion}
${fromCases}
}
static ${toValue} toJs(jsi::Runtime &rt, ${enumName} value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static ${toValue} toJs(jsi::Runtime &rt, ${enumName} value) {
${toCases}
}
};`;
@@ -211,7 +211,7 @@ enum SampleTurboModuleCxxNumEnum { ONE, TWO };
template <>
struct Bridging<SampleTurboModuleCxxNumEnum> {
static SampleTurboModuleCxxNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleCxxNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 1) {
return SampleTurboModuleCxxNumEnum::ONE;
@@ -222,7 +222,7 @@ struct Bridging<SampleTurboModuleCxxNumEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxNumEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxNumEnum value) {
if (value == SampleTurboModuleCxxNumEnum::ONE) {
return bridging::toJs(rt, 1);
} else if (value == SampleTurboModuleCxxNumEnum::TWO) {
@@ -239,7 +239,7 @@ enum SampleTurboModuleCxxFloatEnum { POINT_ZERO, POINT_ONE, POINT_TWO };
template <>
struct Bridging<SampleTurboModuleCxxFloatEnum> {
static SampleTurboModuleCxxFloatEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleCxxFloatEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 0.0f) {
return SampleTurboModuleCxxFloatEnum::POINT_ZERO;
@@ -252,7 +252,7 @@ struct Bridging<SampleTurboModuleCxxFloatEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxFloatEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxFloatEnum value) {
if (value == SampleTurboModuleCxxFloatEnum::POINT_ZERO) {
return bridging::toJs(rt, 0.0f);
} else if (value == SampleTurboModuleCxxFloatEnum::POINT_ONE) {
@@ -271,7 +271,7 @@ enum SampleTurboModuleCxxStringEnum { HELLO, GoodBye };
template <>
struct Bridging<SampleTurboModuleCxxStringEnum> {
static SampleTurboModuleCxxStringEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleCxxStringEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"hello\\") {
return SampleTurboModuleCxxStringEnum::HELLO;
@@ -282,7 +282,7 @@ struct Bridging<SampleTurboModuleCxxStringEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, SampleTurboModuleCxxStringEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, SampleTurboModuleCxxStringEnum value) {
if (value == SampleTurboModuleCxxStringEnum::HELLO) {
return bridging::toJs(rt, \\"hello\\");
} else if (value == SampleTurboModuleCxxStringEnum::GoodBye) {
@@ -1209,7 +1209,7 @@ enum SampleTurboModuleNumEnum { ONE, TWO };
template <>
struct Bridging<SampleTurboModuleNumEnum> {
static SampleTurboModuleNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleNumEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 1) {
return SampleTurboModuleNumEnum::ONE;
@@ -1220,7 +1220,7 @@ struct Bridging<SampleTurboModuleNumEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleNumEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleNumEnum value) {
if (value == SampleTurboModuleNumEnum::ONE) {
return bridging::toJs(rt, 1);
} else if (value == SampleTurboModuleNumEnum::TWO) {
@@ -1237,7 +1237,7 @@ enum SampleTurboModuleFloatEnum { POINT_ZERO, POINT_ONE, POINT_TWO };
template <>
struct Bridging<SampleTurboModuleFloatEnum> {
static SampleTurboModuleFloatEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleFloatEnum fromJs(jsi::Runtime &rt, const jsi::Value &rawValue) {
double value = (double)rawValue.asNumber();
if (value == 0.0f) {
return SampleTurboModuleFloatEnum::POINT_ZERO;
@@ -1250,7 +1250,7 @@ struct Bridging<SampleTurboModuleFloatEnum> {
}
}
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleFloatEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleFloatEnum value) {
if (value == SampleTurboModuleFloatEnum::POINT_ZERO) {
return bridging::toJs(rt, 0.0f);
} else if (value == SampleTurboModuleFloatEnum::POINT_ONE) {
@@ -1269,7 +1269,7 @@ enum SampleTurboModuleStringEnum { HELLO, GoodBye };
template <>
struct Bridging<SampleTurboModuleStringEnum> {
static SampleTurboModuleStringEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue, const std::shared_ptr<CallInvoker> &jsInvoker) {
static SampleTurboModuleStringEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) {
std::string value = rawValue.utf8(rt);
if (value == \\"hello\\") {
return SampleTurboModuleStringEnum::HELLO;
@@ -1280,7 +1280,7 @@ struct Bridging<SampleTurboModuleStringEnum> {
}
}
static jsi::String toJs(jsi::Runtime &rt, SampleTurboModuleStringEnum value, const std::shared_ptr<CallInvoker> &jsInvoker) {
static jsi::String toJs(jsi::Runtime &rt, SampleTurboModuleStringEnum value) {
if (value == SampleTurboModuleStringEnum::HELLO) {
return bridging::toJs(rt, \\"hello\\");
} else if (value == SampleTurboModuleStringEnum::GoodBye) {
@@ -1,6 +1,6 @@
{
"name": "@react-native/gradle-plugin",
"version": "0.72.7",
"version": "0.72.10",
"description": "⚛️ Gradle Plugin for React Native",
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-gradle-plugin",
"repository": {
@@ -19,6 +19,7 @@ import com.facebook.react.utils.BackwardCompatUtils.configureBackwardCompatibili
import com.facebook.react.utils.DependencyUtils.configureDependencies
import com.facebook.react.utils.DependencyUtils.configureRepositories
import com.facebook.react.utils.DependencyUtils.readVersionAndGroupStrings
import com.facebook.react.utils.JdkConfiguratorUtils.configureJavaToolChains
import com.facebook.react.utils.JsonUtils
import com.facebook.react.utils.NdkConfiguratorUtils.configureReactNativeNdk
import com.facebook.react.utils.ProjectUtils.needsCodegenFromPackageJson
@@ -78,6 +79,9 @@ class ReactPlugin : Plugin<Project> {
project.pluginManager.withPlugin("com.android.library") {
configureCodegen(project, extension, rootExtension, isLibrary = true)
}
// App and Library Configurations
configureJavaToolChains(project)
}
private fun checkJvmVersion(project: Project) {
@@ -174,6 +174,7 @@ abstract class BundleHermesCTask : DefaultTask() {
return windowsAwareCommandLine(
hermesCommand,
"-emit-binary",
"-max-diagnostic-width=80",
"-out",
bytecodeFile.cliPath(rootFile),
bundleFile.cliPath(rootFile),
@@ -69,6 +69,16 @@ internal object DependencyUtils {
.using(it.module("${groupString}:hermes-android:${versionString}"))
.because(
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.")
if (groupString != DEFAULT_GROUP_STRING) {
it.substitute(it.module("com.facebook.react:react-android"))
.using(it.module("${groupString}:react-android:${versionString}"))
.because(
"The react-android dependency was modified to use the correct Maven group.")
it.substitute(it.module("com.facebook.react:hermes-android"))
.using(it.module("${groupString}:hermes-android:${versionString}"))
.because(
"The hermes-android dependency was modified to use the correct Maven group.")
}
}
configuration.resolutionStrategy.force(
"${groupString}:react-android:${versionString}",
@@ -0,0 +1,40 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.utils
import com.android.build.api.variant.AndroidComponentsExtension
import com.facebook.react.utils.PropertyUtils.INTERNAL_DISABLE_JAVA_VERSION_ALIGNMENT
import org.gradle.api.Action
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.plugins.AppliedPlugin
internal object JdkConfiguratorUtils {
/**
* Function that takes care of configuring the JDK toolchain for all the projects projects. As we
* do decide the JDK version based on the AGP version that RNGP brings over, here we can safely
* configure the toolchain to 11.
*/
fun configureJavaToolChains(input: Project) {
if (input.hasProperty(INTERNAL_DISABLE_JAVA_VERSION_ALIGNMENT)) {
return
}
input.rootProject.allprojects { project ->
val action =
Action<AppliedPlugin> {
project.extensions.getByType(AndroidComponentsExtension::class.java).finalizeDsl {
ext ->
ext.compileOptions.sourceCompatibility = JavaVersion.VERSION_11
ext.compileOptions.targetCompatibility = JavaVersion.VERSION_11
}
}
project.pluginManager.withPlugin("com.android.application", action)
project.pluginManager.withPlugin("com.android.library", action)
}
}
}
@@ -40,16 +40,22 @@ internal object NdkConfiguratorUtils {
// Parameters should be provided in an additive manner (do not override what
// the user provided, but allow for sensible defaults).
val cmakeArgs = ext.defaultConfig.externalNativeBuild.cmake.arguments
if ("-DPROJECT_BUILD_DIR" !in cmakeArgs) {
if (cmakeArgs.none { it.startsWith("-DPROJECT_BUILD_DIR") }) {
cmakeArgs.add("-DPROJECT_BUILD_DIR=${project.buildDir}")
}
if ("-DREACT_ANDROID_DIR" !in cmakeArgs) {
if (cmakeArgs.none { it.startsWith("-DREACT_ANDROID_DIR") }) {
cmakeArgs.add(
"-DREACT_ANDROID_DIR=${extension.reactNativeDir.file("ReactAndroid").get().asFile}")
}
if ("-DANDROID_STL" !in cmakeArgs) {
if (cmakeArgs.none { it.startsWith("-DANDROID_STL") }) {
cmakeArgs.add("-DANDROID_STL=c++_shared")
}
// Due to the new NDK toolchain file, the C++ flags gets overridden between compilation
// units. This is causing some libraries to don't be compiled with -DANDROID and other
// crucial flags. This can be revisited once we bump to NDK 25/26
if (cmakeArgs.none { it.startsWith("-DANDROID_USE_LEGACY_TOOLCHAIN_FILE") }) {
cmakeArgs.add("-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON")
}
val architectures = project.getReactNativeArchitectures()
// abiFilters are split ABI are not compatible each other, so we set the abiFilters
@@ -0,0 +1,18 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.utils
/** Collection of all the Gradle Propreties that are accepted by React Native Gradle Plugin. */
object PropertyUtils {
/**
* Internal Property that acts as a killswitch to configure the JDK version and align it for app
* and all the libraries.
*/
const val INTERNAL_DISABLE_JAVA_VERSION_ALIGNMENT = "react.internal.disableJavaVersionAlignment"
}
@@ -341,11 +341,12 @@ class BundleHermesCTaskTest {
assertEquals(customHermesc, hermesCommand[0])
assertEquals("-emit-binary", hermesCommand[1])
assertEquals("-out", hermesCommand[2])
assertEquals(bytecodeFile.absolutePath, hermesCommand[3])
assertEquals(bundleFile.absolutePath, hermesCommand[4])
assertEquals("my-custom-hermes-flag", hermesCommand[5])
assertEquals(6, hermesCommand.size)
assertEquals("-max-diagnostic-width=80", hermesCommand[2])
assertEquals("-out", hermesCommand[3])
assertEquals(bytecodeFile.absolutePath, hermesCommand[4])
assertEquals(bundleFile.absolutePath, hermesCommand[5])
assertEquals("my-custom-hermes-flag", hermesCommand[6])
assertEquals(7, hermesCommand.size)
}
@Test
@@ -366,11 +367,12 @@ class BundleHermesCTaskTest {
assertEquals("/c", hermesCommand[1])
assertEquals(customHermesc, hermesCommand[2])
assertEquals("-emit-binary", hermesCommand[3])
assertEquals("-out", hermesCommand[4])
assertEquals(bytecodeFile.relativeTo(tempFolder.root).path, hermesCommand[5])
assertEquals(bundleFile.relativeTo(tempFolder.root).path, hermesCommand[6])
assertEquals("my-custom-hermes-flag", hermesCommand[7])
assertEquals(8, hermesCommand.size)
assertEquals("-max-diagnostic-width=80", hermesCommand[4])
assertEquals("-out", hermesCommand[5])
assertEquals(bytecodeFile.relativeTo(tempFolder.root).path, hermesCommand[6])
assertEquals(bundleFile.relativeTo(tempFolder.root).path, hermesCommand[7])
assertEquals("my-custom-hermes-flag", hermesCommand[8])
assertEquals(9, hermesCommand.size)
}
@Test
@@ -94,6 +94,11 @@
*/
- (UIViewController *)createRootViewController;
/// This method controls whether the App will use RuntimeScheduler. Only applicable in the legacy architecture.
///
/// @return: `YES` to use RuntimeScheduler, `NO` to use JavaScript scheduler. The default value is `YES`.
- (BOOL)runtimeSchedulerEnabled;
#if RCT_NEW_ARCH_ENABLED
/// The TurboModule manager
@@ -6,33 +6,41 @@
*/
#import "RCTAppDelegate.h"
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTRootView.h>
#import <React/RCTRuntimeExecutorFromBridge.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import "RCTAppSetupUtils.h"
#if RCT_NEW_ARCH_ENABLED
#import <React/CoreModulesPlugins.h>
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTComponentViewFactory.h>
#import <React/RCTComponentViewProtocol.h>
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
#import <React/RCTLegacyViewManagerInteropComponentView.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <ReactCommon/RCTTurboModuleManager.h>
#import <react/config/ReactNativeConfig.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h>
#import "RCTLegacyInteropComponents.h"
static NSString *const kRNConcurrentRoot = @"concurrentRoot";
@interface RCTAppDelegate () <RCTTurboModuleManagerDelegate, RCTCxxBridgeDelegate> {
@interface RCTAppDelegate () <RCTTurboModuleManagerDelegate> {
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
facebook::react::ContextContainer::Shared _contextContainer;
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
}
@end
#endif
@interface RCTAppDelegate () <RCTCxxBridgeDelegate> {
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
}
@end
@implementation RCTAppDelegate
#if RCT_NEW_ARCH_ENABLED
@@ -126,21 +134,34 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
return [UIViewController new];
}
#if RCT_NEW_ARCH_ENABLED
- (BOOL)runtimeSchedulerEnabled
{
return YES;
}
#pragma mark - RCTCxxBridgeDelegate
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
_runtimeScheduler = _runtimeScheduler =
std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
#if RCT_NEW_ARCH_ENABLED
_runtimeScheduler = std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
std::shared_ptr<facebook::react::CallInvoker> callInvoker =
std::make_shared<facebook::react::RuntimeSchedulerCallInvoker>(_runtimeScheduler);
self.turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self jsInvoker:callInvoker];
_contextContainer->erase("RuntimeScheduler");
_contextContainer->insert("RuntimeScheduler", _runtimeScheduler);
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager, _runtimeScheduler);
return RCTAppSetupDefaultJsExecutorFactory(bridge, self.turboModuleManager, _runtimeScheduler);
#else
if (self.runtimeSchedulerEnabled) {
_runtimeScheduler = std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
}
return RCTAppSetupJsExecutorFactoryForOldArch(bridge, _runtimeScheduler);
#endif
}
#pragma mark RCTTurboModuleManagerDelegate
#if RCT_NEW_ARCH_ENABLED
#pragma mark - RCTTurboModuleManagerDelegate
- (Class)getModuleClassFromName:(const char *)name
{
@@ -11,7 +11,7 @@
#ifdef __cplusplus
#if RCT_NEW_ARCH_ENABLED
#import <memory>
#ifndef RCT_USE_HERMES
#if __has_include(<reacthermes/HermesExecutorFactory.h>)
@@ -27,21 +27,27 @@
#import <React/JSCExecutorFactory.h>
#endif
#if RCT_NEW_ARCH_ENABLED
#import <ReactCommon/RCTTurboModuleManager.h>
#endif
#if RCT_NEW_ARCH_ENABLED
// Forward declaration to decrease compilation coupling
namespace facebook::react {
class RuntimeScheduler;
}
#if RCT_NEW_ARCH_ENABLED
RCT_EXTERN id<RCTTurboModule> RCTAppSetupDefaultModuleFromClass(Class moduleClass);
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupDefaultJsExecutorFactory(
RCTBridge *bridge,
RCTTurboModuleManager *turboModuleManager,
std::shared_ptr<facebook::react::RuntimeScheduler> const &runtimeScheduler);
#else
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupJsExecutorFactoryForOldArch(
RCTBridge *bridge,
std::shared_ptr<facebook::react::RuntimeScheduler> const &runtimeScheduler);
#endif
#endif // __cplusplus
@@ -7,6 +7,10 @@
#import "RCTAppSetupUtils.h"
#import <React/RCTJSIExecutorRuntimeInstaller.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>
#if RCT_NEW_ARCH_ENABLED
// Turbo Module
#import <React/CoreModulesPlugins.h>
@@ -15,7 +19,6 @@
#import <React/RCTGIFImageDecoder.h>
#import <React/RCTHTTPRequestHandler.h>
#import <React/RCTImageLoader.h>
#import <React/RCTJSIExecutorRuntimeInstaller.h>
#import <React/RCTLocalAssetImageLoader.h>
#import <React/RCTNetworking.h>
@@ -135,4 +138,25 @@ std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupDefaultJsExecutor
}));
}
#else
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupJsExecutorFactoryForOldArch(
RCTBridge *bridge,
std::shared_ptr<facebook::react::RuntimeScheduler> const &runtimeScheduler)
{
#if RCT_USE_HERMES
return std::make_unique<facebook::react::HermesExecutorFactory>(
#else
return std::make_unique<facebook::react::JSCExecutorFactory>(
#endif
facebook::react::RCTJSIExecutorRuntimeInstaller([bridge, runtimeScheduler](facebook::jsi::Runtime &runtime) {
if (!bridge) {
return;
}
if (runtimeScheduler) {
facebook::react::RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime, runtimeScheduler);
}
}));
}
#endif
@@ -47,6 +47,9 @@ header_search_paths = [
"$(PODS_CONFIGURATION_BUILD_DIR)/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core",
"$(PODS_CONFIGURATION_BUILD_DIR)/React-NativeModulesApple/React_NativeModulesApple.framework/Headers",
"$(PODS_CONFIGURATION_BUILD_DIR)/React-RCTFabric/RCTFabric.framework/Headers/",
"$(PODS_CONFIGURATION_BUILD_DIR)/React-utils/React_utils.framework/Headers/",
"$(PODS_CONFIGURATION_BUILD_DIR)/React-debug/React_debug.framework/Headers/",
"$(PODS_CONFIGURATION_BUILD_DIR)/React-runtimescheduler/React_runtimescheduler.framework/Headers/",
] : []).map{|p| "\"#{p}\""}.join(" ")
Pod::Spec.new do |s|
@@ -75,15 +78,29 @@ Pod::Spec.new do |s|
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "ReactCommon/turbomodule/core"
s.dependency "React-RCTNetwork"
s.dependency "React-RCTImage"
s.dependency "React-NativeModulesApple"
s.dependency "React-CoreModules"
s.dependency "React-runtimescheduler"
if ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == "1"
s.dependency "React-hermes"
else
s.dependency "React-jsc"
end
if is_new_arch_enabled
s.dependency "React-RCTFabric"
s.dependency "React-graphics"
s.dependency "React-utils"
s.dependency "React-debug"
s.script_phases = {
:name => "Generate Legacy Components Interop",
:script => "
. ${PODS_ROOT}/../.xcode.env
WITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"
source $WITH_ENVIRONMENT
${NODE_BINARY} ${REACT_NATIVE_PATH}/scripts/codegen/generate-legacy-interop-components.js -p #{ENV['APP_PATH']} -o ${REACT_NATIVE_PATH}/Libraries/AppDelegate
",
:execution_position => :before_compile,
@@ -692,7 +692,6 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig = {
fontStyle: true,
textShadowOffset: true,
selectionColor: {process: require('../../StyleSheet/processColor').default},
selection: true,
placeholderTextColor: {
process: require('../../StyleSheet/processColor').default,
},
@@ -289,92 +289,6 @@ export interface TextInputIOSProps {
* @see https://reactnative.dev/docs/textinput#props
*/
export interface TextInputAndroidProps {
/**
* Specifies autocomplete hints for the system, so it can provide autofill. On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set `autoComplete` to `off`.
*
* *Android Only*
*
* Possible values for `autoComplete` are:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `cc-number`
* - `email`
* - `gender`
* - `name`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `postal-code`
* - `street-address`
* - `sms-otp`
* - `tel`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username`
* - `username-new`
* - `off`
*/
autoComplete?:
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'email'
| 'gender'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'username'
| 'username-new'
| 'off'
| undefined;
/**
* When provided it will set the color of the cursor (or "caret") in the component.
* Unlike the behavior of `selectionColor` the cursor color will be set independently
@@ -558,6 +472,127 @@ export interface TextInputProps
*/
autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters' | undefined;
/**
* Specifies autocomplete hints for the system, so it can provide autofill.
* On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set autoComplete to off.
*
* The following values work across platforms:
*
* - `additional-name`
* - `address-line1`
* - `address-line2`
* - `cc-number`
* - `country`
* - `current-password`
* - `email`
* - `family-name`
* - `given-name`
* - `honorific-prefix`
* - `honorific-suffix`
* - `name`
* - `new-password`
* - `off`
* - `one-time-code`
* - `postal-code`
* - `street-address`
* - `tel`
* - `username`
*
* The following values work on iOS only:
*
* - `nickname`
* - `organization`
* - `organization-title`
* - `url`
*
* The following values work on Android only:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `gender`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `sms-otp`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username-new`
*/
autoComplete?:
| 'additional-name'
| 'address-line1'
| 'address-line2'
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'country'
| 'current-password'
| 'email'
| 'family-name'
| 'gender'
| 'given-name'
| 'honorific-prefix'
| 'honorific-suffix'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'new-password'
| 'nickname'
| 'one-time-code'
| 'organization'
| 'organization-title'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'url'
| 'username'
| 'username-new'
| 'off'
| undefined;
/**
* If false, disables auto-correct.
* The default value is true.
@@ -196,36 +196,6 @@ export type enterKeyHintType =
type PasswordRules = string;
type IOSProps = $ReadOnly<{|
/**
* Give the keyboard and the system information about the
* expected semantic meaning for the content that users enter.
* @platform ios
*/
autoComplete?: ?(
| 'address-line1'
| 'address-line2'
| 'cc-number'
| 'current-password'
| 'country'
| 'email'
| 'name'
| 'additional-name'
| 'family-name'
| 'given-name'
| 'nickname'
| 'honorific-prefix'
| 'honorific-suffix'
| 'new-password'
| 'off'
| 'one-time-code'
| 'organization'
| 'organization-title'
| 'postal-code'
| 'street-address'
| 'tel'
| 'url'
| 'username'
),
/**
* When the clear button should appear on the right side of the text view.
* This property is supported only for single-line TextInput component.
@@ -328,111 +298,6 @@ type IOSProps = $ReadOnly<{|
|}>;
type AndroidProps = $ReadOnly<{|
/**
* Specifies autocomplete hints for the system, so it can provide autofill. On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set `autoComplete` to `off`.
*
* *Android Only*
*
* Possible values for `autoComplete` are:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `cc-number`
* - `email`
* - `gender`
* - `name`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `postal-code`
* - `street-address`
* - `sms-otp`
* - `tel`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username`
* - `username-new`
* - `off`
*
* @platform android
*/
autoComplete?: ?(
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'email'
| 'gender'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'username'
| 'username-new'
| 'off'
// additional HTML autocomplete values
| 'address-line1'
| 'address-line2'
| 'bday'
| 'bday-day'
| 'bday-month'
| 'bday-year'
| 'country'
| 'current-password'
| 'honorific-prefix'
| 'honorific-suffix'
| 'additional-name'
| 'family-name'
| 'given-name'
| 'new-password'
| 'one-time-code'
| 'sex'
),
/**
* When provided it will set the color of the cursor (or "caret") in the component.
* Unlike the behavior of `selectionColor` the cursor color will be set independently
@@ -533,6 +398,127 @@ export type Props = $ReadOnly<{|
*/
autoCapitalize?: ?AutoCapitalize,
/**
* Specifies autocomplete hints for the system, so it can provide autofill.
* On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set autoComplete to off.
*
* The following values work across platforms:
*
* - `additional-name`
* - `address-line1`
* - `address-line2`
* - `cc-number`
* - `country`
* - `current-password`
* - `email`
* - `family-name`
* - `given-name`
* - `honorific-prefix`
* - `honorific-suffix`
* - `name`
* - `new-password`
* - `off`
* - `one-time-code`
* - `postal-code`
* - `street-address`
* - `tel`
* - `username`
*
* The following values work on iOS only:
*
* - `nickname`
* - `organization`
* - `organization-title`
* - `url`
*
* The following values work on Android only:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `gender`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `sms-otp`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username-new`
*/
autoComplete?: ?(
| 'additional-name'
| 'address-line1'
| 'address-line2'
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'country'
| 'current-password'
| 'email'
| 'family-name'
| 'gender'
| 'given-name'
| 'honorific-prefix'
| 'honorific-suffix'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'new-password'
| 'nickname'
| 'one-time-code'
| 'organization'
| 'organization-title'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'url'
| 'username'
| 'username-new'
| 'off'
),
/**
* If `false`, disables auto-correct. The default value is `true`.
*/
@@ -234,36 +234,6 @@ export type enterKeyHintType =
type PasswordRules = string;
type IOSProps = $ReadOnly<{|
/**
* Give the keyboard and the system information about the
* expected semantic meaning for the content that users enter.
* @platform ios
*/
autoComplete?: ?(
| 'address-line1'
| 'address-line2'
| 'cc-number'
| 'current-password'
| 'country'
| 'email'
| 'name'
| 'additional-name'
| 'family-name'
| 'given-name'
| 'nickname'
| 'honorific-prefix'
| 'honorific-suffix'
| 'new-password'
| 'off'
| 'one-time-code'
| 'organization'
| 'organization-title'
| 'postal-code'
| 'street-address'
| 'tel'
| 'url'
| 'username'
),
/**
* When the clear button should appear on the right side of the text view.
* This property is supported only for single-line TextInput component.
@@ -369,111 +339,6 @@ type IOSProps = $ReadOnly<{|
|}>;
type AndroidProps = $ReadOnly<{|
/**
* Specifies autocomplete hints for the system, so it can provide autofill. On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set `autoComplete` to `off`.
*
* *Android Only*
*
* Possible values for `autoComplete` are:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `cc-number`
* - `email`
* - `gender`
* - `name`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `postal-code`
* - `street-address`
* - `sms-otp`
* - `tel`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username`
* - `username-new`
* - `off`
*
* @platform android
*/
autoComplete?: ?(
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'email'
| 'gender'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'username'
| 'username-new'
| 'off'
// additional HTML autocomplete values
| 'address-line1'
| 'address-line2'
| 'bday'
| 'bday-day'
| 'bday-month'
| 'bday-year'
| 'country'
| 'current-password'
| 'honorific-prefix'
| 'honorific-suffix'
| 'additional-name'
| 'family-name'
| 'given-name'
| 'new-password'
| 'one-time-code'
| 'sex'
),
/**
* When provided it will set the color of the cursor (or "caret") in the component.
* Unlike the behavior of `selectionColor` the cursor color will be set independently
@@ -574,6 +439,127 @@ export type Props = $ReadOnly<{|
*/
autoCapitalize?: ?AutoCapitalize,
/**
* Specifies autocomplete hints for the system, so it can provide autofill.
* On Android, the system will always attempt to offer autofill by using heuristics to identify the type of content.
* To disable autocomplete, set autoComplete to off.
*
* The following values work across platforms:
*
* - `additional-name`
* - `address-line1`
* - `address-line2`
* - `cc-number`
* - `country`
* - `current-password`
* - `email`
* - `family-name`
* - `given-name`
* - `honorific-prefix`
* - `honorific-suffix`
* - `name`
* - `new-password`
* - `off`
* - `one-time-code`
* - `postal-code`
* - `street-address`
* - `tel`
* - `username`
*
* The following values work on iOS only:
*
* - `nickname`
* - `organization`
* - `organization-title`
* - `url`
*
* The following values work on Android only:
*
* - `birthdate-day`
* - `birthdate-full`
* - `birthdate-month`
* - `birthdate-year`
* - `cc-csc`
* - `cc-exp`
* - `cc-exp-day`
* - `cc-exp-month`
* - `cc-exp-year`
* - `gender`
* - `name-family`
* - `name-given`
* - `name-middle`
* - `name-middle-initial`
* - `name-prefix`
* - `name-suffix`
* - `password`
* - `password-new`
* - `postal-address`
* - `postal-address-country`
* - `postal-address-extended`
* - `postal-address-extended-postal-code`
* - `postal-address-locality`
* - `postal-address-region`
* - `sms-otp`
* - `tel-country-code`
* - `tel-national`
* - `tel-device`
* - `username-new`
*/
autoComplete?: ?(
| 'additional-name'
| 'address-line1'
| 'address-line2'
| 'birthdate-day'
| 'birthdate-full'
| 'birthdate-month'
| 'birthdate-year'
| 'cc-csc'
| 'cc-exp'
| 'cc-exp-day'
| 'cc-exp-month'
| 'cc-exp-year'
| 'cc-number'
| 'country'
| 'current-password'
| 'email'
| 'family-name'
| 'gender'
| 'given-name'
| 'honorific-prefix'
| 'honorific-suffix'
| 'name'
| 'name-family'
| 'name-given'
| 'name-middle'
| 'name-middle-initial'
| 'name-prefix'
| 'name-suffix'
| 'new-password'
| 'nickname'
| 'one-time-code'
| 'organization'
| 'organization-title'
| 'password'
| 'password-new'
| 'postal-address'
| 'postal-address-country'
| 'postal-address-extended'
| 'postal-address-extended-postal-code'
| 'postal-address-locality'
| 'postal-address-region'
| 'postal-code'
| 'street-address'
| 'sms-otp'
| 'tel'
| 'tel-country-code'
| 'tel-national'
| 'tel-device'
| 'url'
| 'username'
| 'username-new'
| 'off'
),
/**
* If `false`, disables auto-correct. The default value is `true`.
*/
@@ -1080,27 +1066,19 @@ function InternalTextInput(props: Props): React.Node {
accessibilityState,
id,
tabIndex,
selection: propsSelection,
...otherProps
} = props;
const inputRef = useRef<null | React.ElementRef<HostComponent<mixed>>>(null);
// Android sends a "onTextChanged" event followed by a "onSelectionChanged" event, for
// the same "most recent event count".
// For controlled selection, that means that immediately after text is updated,
// a controlled component will pass in the *previous* selection, even if the controlled
// component didn't mean to modify the selection at all.
// Therefore, we ignore selections and pass them through until the selection event has
// been sent.
// Note that this mitigation is NOT needed for Fabric.
// discovered when upgrading react-hooks
// eslint-disable-next-line react-hooks/exhaustive-deps
let selection: ?Selection =
props.selection == null
const selection: ?Selection =
propsSelection == null
? null
: {
start: props.selection.start,
end: props.selection.end ?? props.selection.start,
start: propsSelection.start,
end: propsSelection.end ?? propsSelection.start,
};
const [mostRecentEventCount, setMostRecentEventCount] = useState<number>(0);
@@ -1112,12 +1090,6 @@ function InternalTextInput(props: Props): React.Node {
|}>({selection, mostRecentEventCount});
const lastNativeSelection = lastNativeSelectionState.selection;
const lastNativeSelectionEventCount =
lastNativeSelectionState.mostRecentEventCount;
if (lastNativeSelectionEventCount < mostRecentEventCount) {
selection = null;
}
let viewCommands;
if (AndroidTextInputCommands) {
@@ -1517,7 +1489,6 @@ function InternalTextInput(props: Props): React.Node {
onScroll={_onScroll}
onSelectionChange={_onSelectionChange}
placeholder={placeholder}
selection={selection}
style={style}
text={text}
textBreakStrategy={props.textBreakStrategy}
+1 -1
View File
@@ -13,5 +13,5 @@ exports.version = {
major: 0,
minor: 72,
patch: 0,
prerelease: 'rc.3',
prerelease: 'rc.6',
};
@@ -111,6 +111,7 @@ exports[`FlatList renders all the bells and whistles 1`] = `
<RCTRefreshControl />
<View>
<View
collapsable={false}
onLayout={[Function]}
>
<header />
@@ -243,6 +243,7 @@ exports[`SectionList renders all the bells and whistles 1`] = `
<RCTRefreshControl />
<View>
<View
collapsable={false}
onLayout={[Function]}
>
<header
@@ -75,7 +75,6 @@ const PERMISSIONS = Object.freeze({
ANSWER_PHONE_CALLS: 'android.permission.ANSWER_PHONE_CALLS',
READ_PHONE_NUMBERS: 'android.permission.READ_PHONE_NUMBERS',
UWB_RANGING: 'android.permission.UWB_RANGING',
POST_NOTIFICATION: 'android.permission.POST_NOTIFICATIONS', // Remove in 0.72
POST_NOTIFICATIONS: 'android.permission.POST_NOTIFICATIONS',
NEARBY_WIFI_DEVICES: 'android.permission.NEARBY_WIFI_DEVICES',
});
@@ -107,7 +106,6 @@ class PermissionsAndroid {
CAMERA: string,
GET_ACCOUNTS: string,
NEARBY_WIFI_DEVICES: string,
POST_NOTIFICATION: string, // Remove in 0.72
POST_NOTIFICATIONS: string,
PROCESS_OUTGOING_CALLS: string,
READ_CALENDAR: string,
@@ -18,7 +18,7 @@ type FlexAlignType =
| 'stretch'
| 'baseline';
type DimensionValue =
export type DimensionValue =
| number
| 'auto'
| `${number}%`
@@ -79,15 +79,9 @@ export interface FlexStyle {
| undefined;
left?: DimensionValue | undefined;
margin?: DimensionValue | undefined;
marginBlock?: DimensionValue | undefined;
marginBlockEnd?: DimensionValue | undefined;
marginBlockStart?: DimensionValue | undefined;
marginBottom?: DimensionValue | undefined;
marginEnd?: DimensionValue | undefined;
marginHorizontal?: DimensionValue | undefined;
marginInline?: DimensionValue | undefined;
marginInlineEnd?: DimensionValue | undefined;
marginInlineStart?: DimensionValue | undefined;
marginLeft?: DimensionValue | undefined;
marginRight?: DimensionValue | undefined;
marginStart?: DimensionValue | undefined;
@@ -100,14 +94,8 @@ export interface FlexStyle {
overflow?: 'visible' | 'hidden' | 'scroll' | undefined;
padding?: DimensionValue | undefined;
paddingBottom?: DimensionValue | undefined;
paddingBlock?: DimensionValue | undefined;
paddingBlockEnd?: DimensionValue | undefined;
paddingBlockStart?: DimensionValue | undefined;
paddingEnd?: DimensionValue | undefined;
paddingHorizontal?: DimensionValue | undefined;
paddingInline?: DimensionValue | undefined;
paddingInlineEnd?: DimensionValue | undefined;
paddingInlineStart?: DimensionValue | undefined;
paddingLeft?: DimensionValue | undefined;
paddingRight?: DimensionValue | undefined;
paddingStart?: DimensionValue | undefined;
+6 -4
View File
@@ -126,11 +126,13 @@ Pod::Spec.new do |s|
end
s.dependency "RCT-Folly", folly_version
s.dependency "React-cxxreact", version
s.dependency "React-perflogger", version
s.dependency "React-jsi", version
s.dependency "React-jsiexecutor", version
s.dependency "React-cxxreact"
s.dependency "React-perflogger"
s.dependency "React-jsi"
s.dependency "React-jsiexecutor"
s.dependency "React-utils"
s.dependency "SocketRocket", socket_rocket_version
s.dependency "React-runtimeexecutor"
s.dependency "Yoga"
s.dependency "glog"
@@ -312,7 +312,17 @@ static void attemptAsynchronousLoadOfBundleAtURL(
return;
}
RCTSource *source = RCTSourceCreate(scriptURL, data, data.length);
// Prefer `Content-Location` as the canonical source URL, if given, or fall back to scriptURL.
NSURL *sourceURL = scriptURL;
NSString *contentLocationHeader = headers[@"Content-Location"];
if (contentLocationHeader) {
NSURL *contentLocationURL = [NSURL URLWithString:contentLocationHeader relativeToURL:scriptURL];
if (contentLocationURL) {
sourceURL = contentLocationURL;
}
}
RCTSource *source = RCTSourceCreate(sourceURL, data, data.length);
parseHeaders(headers, source);
onComplete(nil, source);
}
@@ -0,0 +1,19 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#ifdef __cplusplus
#import <ReactCommon/RuntimeExecutor.h>
NS_ASSUME_NONNULL_BEGIN
@class RCTBridge;
facebook::react::RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge);
NS_ASSUME_NONNULL_END
#endif
@@ -0,0 +1,56 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTRuntimeExecutorFromBridge.h"
#import <React/RCTAssert.h>
#import <React/RCTBridge+Private.h>
#import <cxxreact/MessageQueueThread.h>
#import <react/utils/ManagedObjectWrapper.h>
using namespace facebook::react;
@interface RCTBridge ()
- (std::shared_ptr<MessageQueueThread>)jsMessageThread;
- (void)invokeAsync:(std::function<void()> &&)func;
@end
RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge)
{
RCTAssert(bridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil.");
auto bridgeWeakWrapper = wrapManagedObjectWeakly([bridge batchedBridge] ?: bridge);
RuntimeExecutor runtimeExecutor = [bridgeWeakWrapper](
std::function<void(facebook::jsi::Runtime & runtime)> &&callback) {
RCTBridge *bridge = unwrapManagedObjectWeakly(bridgeWeakWrapper);
RCTAssert(bridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil at the moment of scheduling a call.");
[bridge invokeAsync:[bridgeWeakWrapper, callback = std::move(callback)]() {
RCTCxxBridge *batchedBridge = (RCTCxxBridge *)unwrapManagedObjectWeakly(bridgeWeakWrapper);
RCTAssert(batchedBridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil at the moment of invocation.");
if (!batchedBridge) {
return;
}
auto runtime = (facebook::jsi::Runtime *)(batchedBridge.runtime);
RCTAssert(
runtime, @"RCTRuntimeExecutorFromBridge: Bridge must have a valid jsi::Runtime at the moment of invocation.");
if (!runtime) {
return;
}
callback(*runtime);
}];
};
return runtimeExecutor;
}
@@ -24,7 +24,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
RCTVersionMajor: @(0),
RCTVersionMinor: @(72),
RCTVersionPatch: @(0),
RCTVersionPrerelease: @"rc.3",
RCTVersionPrerelease: @"rc.6",
};
});
return __rnVersion;
@@ -475,6 +475,7 @@ struct RCTInstanceCallback : public InstanceCallback {
// Load the source asynchronously, then store it for later execution.
dispatch_group_enter(prepareBridge);
__block NSData *sourceCode;
__block NSURL *sourceURL = self.bundleURL;
#if (RCT_DEV | RCT_ENABLE_LOADING_VIEW) && __has_include(<React/RCTDevLoadingViewProtocol.h>)
{
@@ -490,6 +491,9 @@ struct RCTInstanceCallback : public InstanceCallback {
}
sourceCode = source.data;
if (source.url) {
sourceURL = source.url;
}
dispatch_group_leave(prepareBridge);
}
onProgress:^(RCTLoadingProgress *progressData) {
@@ -504,7 +508,7 @@ struct RCTInstanceCallback : public InstanceCallback {
dispatch_group_notify(prepareBridge, dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
RCTCxxBridge *strongSelf = weakSelf;
if (sourceCode && strongSelf.loading) {
[strongSelf executeSourceCode:sourceCode sync:NO];
[strongSelf executeSourceCode:sourceCode withSourceURL:sourceURL sync:NO];
}
});
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
@@ -1050,7 +1054,7 @@ struct RCTInstanceCallback : public InstanceCallback {
[_displayLink registerModuleForFrameUpdates:module withModuleData:moduleData];
}
- (void)executeSourceCode:(NSData *)sourceCode sync:(BOOL)sync
- (void)executeSourceCode:(NSData *)sourceCode withSourceURL:(NSURL *)url sync:(BOOL)sync
{
// This will get called from whatever thread was actually executing JS.
dispatch_block_t completion = ^{
@@ -1075,12 +1079,13 @@ struct RCTInstanceCallback : public InstanceCallback {
};
if (sync) {
[self executeApplicationScriptSync:sourceCode url:self.bundleURL];
[self executeApplicationScriptSync:sourceCode url:url];
completion();
} else {
[self enqueueApplicationScript:sourceCode url:self.bundleURL onComplete:completion];
[self enqueueApplicationScript:sourceCode url:url onComplete:completion];
}
// Use the original request URL here - HMRClient uses this to derive the /hot URL and entry point.
[self.devSettings setupHMRClientWithBundleURL:self.bundleURL];
}
@@ -6,7 +6,6 @@
*/
#import <Foundation/Foundation.h>
#import <ReactCommon/RuntimeExecutor.h>
#import <UIKit/UIKit.h>
#import <react/utils/ContextContainer.h>
@@ -15,8 +14,6 @@ NS_ASSUME_NONNULL_BEGIN
@class RCTSurfacePresenter;
@class RCTBridge;
facebook::react::RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge);
/*
* Controls a life-cycle of a Surface Presenter based on Bridge's life-cycle.
* We are moving away from using Bridge.
@@ -15,6 +15,7 @@
#import <React/RCTConstants.h>
#import <React/RCTImageLoader.h>
#import <React/RCTImageLoaderWithAttributionProtocol.h>
#import <React/RCTRuntimeExecutorFromBridge.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterStub.h>
@@ -42,43 +43,6 @@ static ContextContainer::Shared RCTContextContainerFromBridge(RCTBridge *bridge)
return contextContainer;
}
RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge)
{
RCTAssert(bridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil.");
auto bridgeWeakWrapper = wrapManagedObjectWeakly([bridge batchedBridge] ?: bridge);
RuntimeExecutor runtimeExecutor = [bridgeWeakWrapper](
std::function<void(facebook::jsi::Runtime & runtime)> &&callback) {
RCTBridge *bridge = unwrapManagedObjectWeakly(bridgeWeakWrapper);
RCTAssert(bridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil at the moment of scheduling a call.");
[bridge invokeAsync:[bridgeWeakWrapper, callback = std::move(callback)]() {
RCTCxxBridge *batchedBridge = (RCTCxxBridge *)unwrapManagedObjectWeakly(bridgeWeakWrapper);
RCTAssert(batchedBridge, @"RCTRuntimeExecutorFromBridge: Bridge must not be nil at the moment of invocation.");
if (!batchedBridge) {
return;
}
auto runtime = (facebook::jsi::Runtime *)(batchedBridge.runtime);
RCTAssert(
runtime, @"RCTRuntimeExecutorFromBridge: Bridge must have a valid jsi::Runtime at the moment of invocation.");
if (!runtime) {
return;
}
callback(*runtime);
}];
};
return runtimeExecutor;
}
@implementation RCTSurfacePresenterBridgeAdapter {
RCTSurfacePresenter *_Nullable _surfacePresenter;
__weak RCTBridge *_bridge;
@@ -29,7 +29,6 @@ header_search_paths = [
"\"$(PODS_ROOT)/Headers/Private/React-Core\"",
"\"$(PODS_ROOT)/Headers/Public/React-Codegen\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-Codegen/React_Codegen.framework/Headers\"",
]
if ENV['USE_FRAMEWORKS']
@@ -41,6 +40,9 @@ if ENV['USE_FRAMEWORKS']
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-ImageManager/React_ImageManager.framework/Headers\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-utils/React_utils.framework/Headers\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-runtimescheduler/React_runtimescheduler.framework/Headers\""
end
Pod::Spec.new do |s|
@@ -72,6 +74,17 @@ Pod::Spec.new do |s|
s.dependency "React-RCTImage", version
s.dependency "React-ImageManager"
s.dependency "RCT-Folly/Fabric", folly_version
s.dependency "glog"
s.dependency "Yoga"
s.dependency "React-RCTText"
s.dependency "React-utils"
s.dependency "React-runtimescheduler"
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
else
s.dependency "React-jsi"
end
s.test_spec 'Tests' do |test_spec|
test_spec.source_files = "Tests/**/*.{mm}"
@@ -469,7 +469,10 @@ android {
"-DREACT_BUILD_DIR=$buildDir",
"-DANDROID_STL=c++_shared",
"-DANDROID_TOOLCHAIN=clang",
"-DANDROID_PLATFORM=android-21"
"-DANDROID_PLATFORM=android-21",
// Due to https://github.com/android/ndk/issues/1693 we're losing Android
// specific compilation flags. This can be removed once we moved to NDK 25/26
"-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON"
targets "jsijniprofiler",
"reactnativeblob",
@@ -46,7 +46,20 @@ target_include_directories(${CMAKE_PROJECT_NAME}
${CMAKE_CURRENT_SOURCE_DIR}
${PROJECT_BUILD_DIR}/generated/rncli/src/main/jni)
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -Wall -Werror -fexceptions -frtti -std=c++17 -DWITH_INSPECTOR=1 -DLOG_TAG=\"ReactNative\")
target_compile_options(${CMAKE_PROJECT_NAME}
PRIVATE
-Wall
-Werror
# We suppress cpp #error and #warning to don't fail the build
# due to use migrating away from
# #include <react/renderer/graphics/conversions.h>
# This can be removed for React Native 0.73
-Wno-error=cpp
-fexceptions
-frtti
-std=c++17
-DWITH_INSPECTOR=1
-DLOG_TAG=\"ReactNative\")
# Prefab packages from React Native
find_package(ReactAndroid REQUIRED CONFIG)
@@ -1,4 +1,4 @@
VERSION_NAME=0.72.0-rc.3
VERSION_NAME=0.72.0-rc.6
GROUP=com.facebook.react
# JVM Versions
@@ -154,6 +154,9 @@ android {
// We intentionally build Hermes with Intl support only. This is to simplify
// the build setup and to avoid overcomplicating the build-type matrix.
arguments "-DHERMES_ENABLE_INTL=True"
// Due to https://github.com/android/ndk/issues/1693 we're losing Android
// specific compilation flags. This can be removed once we moved to NDK 25/26
arguments "-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON"
targets "libhermes"
}
}
@@ -178,6 +181,8 @@ android {
// This has the (unlucky) side effect of letting AGP call the build
// tasks `configureCMakeRelease` while is actually building the debug flavor.
arguments "-DCMAKE_BUILD_TYPE=Release"
// Adding -O3 to patch the issue here: https://github.com/android/ndk/issues/1740#issuecomment-1198438260
cppFlags "-O3"
}
}
}
@@ -1360,6 +1360,15 @@ public class ReactInstanceManager {
reactContext.initializeWithInstance(catalystInstance);
if (ReactFeatureFlags.unstable_useRuntimeSchedulerAlways) {
// On Old Architecture, we need to initialize the Native Runtime Scheduler so that
// the `nativeRuntimeScheduler` object is registered on JS.
// On New Architecture, this is normally triggered by instantiate a TurboModuleManager.
// Here we invoke getRuntimeScheduler() to trigger the creation of it regardless of the
// architecture so it will always be there.
catalystInstance.getRuntimeScheduler();
}
if (ReactFeatureFlags.useTurboModules && mTMMDelegateBuilder != null) {
TurboModuleManagerDelegate tmmDelegate =
mTMMDelegateBuilder
@@ -42,6 +42,13 @@ public class ReactFeatureFlags {
*/
public static volatile boolean unstable_useFabricInterop = false;
/**
* Should this application always use the Native RuntimeScheduler? If yes, we'll be instantiating
* it over all the architectures (both Old and New). This is intentionally set to true as we want
* to use it more as a kill-switch to turn off this feature to potentially debug issues.
*/
public static volatile boolean unstable_useRuntimeSchedulerAlways = true;
/**
* Feature flag to enable the new bridgeless architecture. Note: Enabling this will force enable
* the following flags: `useTurboModules` & `enableFabricRenderer`.
@@ -18,5 +18,5 @@ public class ReactNativeVersion {
"major", 0,
"minor", 72,
"patch", 0,
"prerelease", "rc.3");
"prerelease", "rc.6");
}
@@ -69,31 +69,6 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode {
protected @Nullable ReactTextViewManagerCallback mReactTextViewManagerCallback;
private static class SetSpanOperation {
protected int start, end;
protected ReactSpan what;
SetSpanOperation(int start, int end, ReactSpan what) {
this.start = start;
this.end = end;
this.what = what;
}
public void execute(SpannableStringBuilder sb, int priority) {
// All spans will automatically extend to the right of the text, but not the left - except
// for spans that start at the beginning of the text.
int spanFlags = Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
if (start == 0) {
spanFlags = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
}
spanFlags &= ~Spannable.SPAN_PRIORITY;
spanFlags |= (priority << Spannable.SPAN_PRIORITY_SHIFT) & Spannable.SPAN_PRIORITY;
sb.setSpan(what, start, end, spanFlags);
}
}
private static void buildSpannedFromShadowNode(
ReactBaseTextShadowNode textShadowNode,
SpannableStringBuilder sb,
@@ -276,8 +251,9 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode {
// While setting the Spans on the final text, we also check whether any of them are inline views
// or images.
int priority = 0;
for (SetSpanOperation op : ops) {
for (int priorityIndex = 0; priorityIndex < ops.size(); priorityIndex++) {
final SetSpanOperation op = ops.get(ops.size() - priorityIndex - 1);
boolean isInlineImage = op.what instanceof TextInlineImageSpan;
if (isInlineImage || op.what instanceof TextInlineViewPlaceholderSpan) {
int height;
@@ -304,9 +280,8 @@ public abstract class ReactBaseTextShadowNode extends LayoutShadowNode {
}
// Actual order of calling {@code execute} does NOT matter,
// but the {@code priority} DOES matter.
op.execute(sb, priority);
priority++;
// but the {@code priorityIndex} DOES matter.
op.execute(sb, priorityIndex);
}
textShadowNode.mTextAttributes.setHeightOfTallestInlineViewOrImage(
@@ -27,8 +27,6 @@ public class ReactTextUpdate {
private final float mPaddingBottom;
private final int mTextAlign;
private final int mTextBreakStrategy;
private final int mSelectionStart;
private final int mSelectionEnd;
private final int mJustificationMode;
/**
@@ -55,35 +53,7 @@ public class ReactTextUpdate {
paddingBottom,
textAlign,
Layout.BREAK_STRATEGY_HIGH_QUALITY,
Layout.JUSTIFICATION_MODE_NONE,
-1,
-1);
}
public ReactTextUpdate(
Spannable text,
int jsEventCounter,
boolean containsImages,
float paddingStart,
float paddingTop,
float paddingEnd,
float paddingBottom,
int textAlign,
int textBreakStrategy,
int justificationMode) {
this(
text,
jsEventCounter,
containsImages,
paddingStart,
paddingTop,
paddingEnd,
paddingBottom,
textAlign,
textBreakStrategy,
justificationMode,
-1,
-1);
Layout.JUSTIFICATION_MODE_NONE);
}
public ReactTextUpdate(
@@ -103,9 +73,7 @@ public class ReactTextUpdate {
UNSET,
textAlign,
textBreakStrategy,
justificationMode,
-1,
-1);
justificationMode);
}
public ReactTextUpdate(
@@ -118,9 +86,7 @@ public class ReactTextUpdate {
float paddingBottom,
int textAlign,
int textBreakStrategy,
int justificationMode,
int selectionStart,
int selectionEnd) {
int justificationMode) {
mText = text;
mJsEventCounter = jsEventCounter;
mContainsImages = containsImages;
@@ -130,8 +96,6 @@ public class ReactTextUpdate {
mPaddingBottom = paddingBottom;
mTextAlign = textAlign;
mTextBreakStrategy = textBreakStrategy;
mSelectionStart = selectionStart;
mSelectionEnd = selectionEnd;
mJustificationMode = justificationMode;
}
@@ -187,12 +151,4 @@ public class ReactTextUpdate {
public int getJustificationMode() {
return mJustificationMode;
}
public int getSelectionStart() {
return mSelectionStart;
}
public int getSelectionEnd() {
return mSelectionEnd;
}
}
@@ -0,0 +1,52 @@
package com.facebook.react.views.text;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import com.facebook.common.logging.FLog;
class SetSpanOperation {
private static final String TAG = "SetSpanOperation";
static final int SPAN_MAX_PRIORITY = Spanned.SPAN_PRIORITY >> Spanned.SPAN_PRIORITY_SHIFT;
protected int start, end;
protected ReactSpan what;
SetSpanOperation(int start, int end, ReactSpan what) {
this.start = start;
this.end = end;
this.what = what;
}
/**
* @param sb builder
* @param priorityIndex index of this operation in the topological sorting which puts operations
* with higher priority before operations with lower priority.
*/
public void execute(SpannableStringBuilder sb, int priorityIndex) {
assert priorityIndex >= 0;
// All spans will automatically extend to the right of the text, but not the left - except
// for spans that start at the beginning of the text.
int spanFlags = Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
if (start == 0) {
spanFlags = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
}
// Calculate priority, assigning the highest values to operations with the highest priority
final int priority = SPAN_MAX_PRIORITY - priorityIndex;
if (priority < 0) {
FLog.w(TAG, "Text tree size exceeded the limit, styling may become unpredictable");
}
// If the computed priority doesn't fit in the flags, clamp it. The effect might not be correct
// in 100% of cases, but doing nothing (as we did in the past) leads to totally random results.
final int effectivePriority = Math.max(priority, 0);
spanFlags &= ~Spannable.SPAN_PRIORITY;
spanFlags |= (effectivePriority << Spannable.SPAN_PRIORITY_SHIFT) & Spannable.SPAN_PRIORITY;
sb.setSpan(what, start, end, spanFlags);
}
}
@@ -213,12 +213,12 @@ public class TextLayoutManager {
// TODO T31905686: add support for inline Images
// While setting the Spans on the final text, we also check whether any of them are images.
int priority = 0;
for (SetSpanOperation op : ops) {
for (int priorityIndex = 0; priorityIndex < ops.size(); ++priorityIndex) {
final SetSpanOperation op = ops.get(ops.size() - priorityIndex - 1);
// Actual order of calling {@code execute} does NOT matter,
// but the {@code priority} DOES matter.
op.execute(sb, priority);
priority++;
// but the {@code priorityIndex} DOES matter.
op.execute(sb, priorityIndex);
}
if (reactTextViewManagerCallback != null) {
@@ -551,30 +551,4 @@ public class TextLayoutManager {
hyphenationFrequency);
return FontMetricsUtil.getFontMetrics(text, layout, sTextPaintInstance, context);
}
// TODO T31905686: This class should be private
public static class SetSpanOperation {
protected int start, end;
protected ReactSpan what;
public SetSpanOperation(int start, int end, ReactSpan what) {
this.start = start;
this.end = end;
this.what = what;
}
public void execute(Spannable sb, int priority) {
// All spans will automatically extend to the right of the text, but not the left - except
// for spans that start at the beginning of the text.
int spanFlags = Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
if (start == 0) {
spanFlags = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
}
spanFlags &= ~Spannable.SPAN_PRIORITY;
spanFlags |= (priority << Spannable.SPAN_PRIORITY_SHIFT) & Spannable.SPAN_PRIORITY;
sb.setSpan(what, start, end, spanFlags);
}
}
}
@@ -227,12 +227,12 @@ public class TextLayoutManagerMapBuffer {
// TODO T31905686: add support for inline Images
// While setting the Spans on the final text, we also check whether any of them are images.
int priority = 0;
for (SetSpanOperation op : ops) {
for (int priorityIndex = 0; priorityIndex < ops.size(); ++priorityIndex) {
final SetSpanOperation op = ops.get(ops.size() - priorityIndex - 1);
// Actual order of calling {@code execute} does NOT matter,
// but the {@code priority} DOES matter.
op.execute(sb, priority);
priority++;
// but the {@code priorityIndex} DOES matter.
op.execute(sb, priorityIndex);
}
if (reactTextViewManagerCallback != null) {
@@ -570,30 +570,4 @@ public class TextLayoutManagerMapBuffer {
hyphenationFrequency);
return FontMetricsUtil.getFontMetrics(text, layout, sTextPaintInstance, context);
}
// TODO T31905686: This class should be private
public static class SetSpanOperation {
protected int start, end;
protected ReactSpan what;
public SetSpanOperation(int start, int end, ReactSpan what) {
this.start = start;
this.end = end;
this.what = what;
}
public void execute(Spannable sb, int priority) {
// All spans will automatically extend to the right of the text, but not the left - except
// for spans that start at the beginning of the text.
int spanFlags = Spannable.SPAN_EXCLUSIVE_INCLUSIVE;
if (start == 0) {
spanFlags = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
}
spanFlags &= ~Spannable.SPAN_PRIORITY;
spanFlags |= (priority << Spannable.SPAN_PRIORITY_SHIFT) & Spannable.SPAN_PRIORITY;
sb.setSpan(what, start, end, spanFlags);
}
}
}
@@ -116,6 +116,7 @@ public class ReactEditText extends AppCompatEditText
private int mFontStyle = UNSET;
private boolean mAutoFocus = false;
private boolean mDidAttachToWindow = false;
private @Nullable String mPlaceholder = null;
private ReactViewBackgroundManager mReactBackgroundManager;
@@ -496,6 +497,13 @@ public class ReactEditText extends AppCompatEditText
setKeyListener(mKeyListener);
}
public void setPlaceholder(@Nullable String placeholder) {
if (!Objects.equals(placeholder, mPlaceholder)) {
mPlaceholder = placeholder;
setHint(placeholder);
}
}
public void setFontFamily(String fontFamily) {
mFontFamily = fontFamily;
mTypefaceDirty = true;
@@ -328,21 +328,19 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
if (!args.isNull(1)) {
String text = args.getString(1);
reactEditText.maybeSetTextFromJS(
getReactTextUpdate(text, mostRecentEventCount, start, end));
reactEditText.maybeSetTextFromJS(getReactTextUpdate(text, mostRecentEventCount));
}
reactEditText.maybeSetSelection(mostRecentEventCount, start, end);
break;
}
}
private ReactTextUpdate getReactTextUpdate(
String text, int mostRecentEventCount, int start, int end) {
private ReactTextUpdate getReactTextUpdate(String text, int mostRecentEventCount) {
SpannableStringBuilder sb = new SpannableStringBuilder();
sb.append(TextTransform.apply(text, TextTransform.UNSET));
return new ReactTextUpdate(
sb, mostRecentEventCount, false, 0, 0, 0, 0, Gravity.NO_GRAVITY, 0, 0, start, end);
sb, mostRecentEventCount, false, 0, 0, 0, 0, Gravity.NO_GRAVITY, 0, 0);
}
@Override
@@ -373,9 +371,9 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
// Ensure that selection is handled correctly on text update
boolean isCurrentSelectionEmpty = view.getSelectionStart() == view.getSelectionEnd();
int selectionStart = update.getSelectionStart();
int selectionEnd = update.getSelectionEnd();
if ((selectionStart == UNSET || selectionEnd == UNSET) && isCurrentSelectionEmpty) {
int selectionStart = UNSET;
int selectionEnd = UNSET;
if (isCurrentSelectionEmpty) {
// if selection is not set by state, shift current selection to ensure constant gap to
// text end
int textLength = view.getText() == null ? 0 : view.getText().length();
@@ -507,7 +505,7 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
@ReactProp(name = "placeholder")
public void setPlaceholder(ReactEditText view, String placeholder) {
view.setHint(placeholder);
view.setPlaceholder(placeholder);
}
@ReactProp(name = "placeholderTextColor", customType = "Color")
@@ -17,7 +17,6 @@ import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import com.facebook.common.logging.FLog;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.uimanager.Spacing;
@@ -44,13 +43,10 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode
@VisibleForTesting public static final String PROP_TEXT = "text";
@VisibleForTesting public static final String PROP_PLACEHOLDER = "placeholder";
@VisibleForTesting public static final String PROP_SELECTION = "selection";
// Represents the {@code text} property only, not possible nested content.
private @Nullable String mText = null;
private @Nullable String mPlaceholder = null;
private int mSelectionStart = UNSET;
private int mSelectionEnd = UNSET;
public ReactTextInputShadowNode(
@Nullable ReactTextViewManagerCallback reactTextViewManagerCallback) {
@@ -165,18 +161,6 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode
@ReactProp(name = PROP_TEXT)
public void setText(@Nullable String text) {
mText = text;
if (text != null) {
// The selection shouldn't be bigger than the length of the text
if (mSelectionStart > text.length()) {
mSelectionStart = text.length();
}
if (mSelectionEnd > text.length()) {
mSelectionEnd = text.length();
}
} else {
mSelectionStart = UNSET;
mSelectionEnd = UNSET;
}
markUpdated();
}
@@ -194,18 +178,6 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode
return mPlaceholder;
}
@ReactProp(name = PROP_SELECTION)
public void setSelection(@Nullable ReadableMap selection) {
mSelectionStart = mSelectionEnd = UNSET;
if (selection == null) return;
if (selection.hasKey("start") && selection.hasKey("end")) {
mSelectionStart = selection.getInt("start");
mSelectionEnd = selection.getInt("end");
markUpdated();
}
}
@Override
public void setTextBreakStrategy(@Nullable String textBreakStrategy) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
@@ -245,9 +217,7 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode
getPadding(Spacing.BOTTOM),
mTextAlign,
mTextBreakStrategy,
mJustificationMode,
mSelectionStart,
mSelectionEnd);
mJustificationMode);
uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), reactTextUpdate);
}
}
@@ -567,19 +567,28 @@ public class ReactViewBackgroundDrawable extends Drawable {
int colorRight = getBorderColor(Spacing.RIGHT);
int colorBottom = getBorderColor(Spacing.BOTTOM);
int borderColor = getBorderColor(Spacing.ALL);
int colorBlock = getBorderColor(Spacing.BLOCK);
int colorBlockStart = getBorderColor(Spacing.BLOCK_START);
int colorBlockEnd = getBorderColor(Spacing.BLOCK_END);
if (isBorderColorDefined(Spacing.BLOCK)) {
colorBottom = colorBlock;
colorTop = colorBlock;
}
if (isBorderColorDefined(Spacing.BLOCK_END)) {
colorBottom = colorBlockEnd;
}
if (isBorderColorDefined(Spacing.BLOCK_START)) {
colorTop = colorBlockStart;
}
// Clip border ONLY if its color is non transparent
if (Color.alpha(colorLeft) != 0
&& Color.alpha(colorTop) != 0
&& Color.alpha(colorRight) != 0
&& Color.alpha(colorBottom) != 0
&& Color.alpha(borderColor) != 0
&& Color.alpha(colorBlock) != 0
&& Color.alpha(colorBlockStart) != 0
&& Color.alpha(colorBlockEnd) != 0) {
&& Color.alpha(borderColor) != 0) {
mInnerClipTempRectForBorderRadius.top += borderWidth.top;
mInnerClipTempRectForBorderRadius.bottom -= borderWidth.bottom;
@@ -885,7 +894,7 @@ public class ReactViewBackgroundDrawable extends Drawable {
/** Compute mInnerTopLeftCorner */
mInnerTopLeftCorner.x = mInnerClipTempRectForBorderRadius.left;
mInnerTopLeftCorner.y = mInnerClipTempRectForBorderRadius.top * 2;
mInnerTopLeftCorner.y = mInnerClipTempRectForBorderRadius.top;
getEllipseIntersectionWithLine(
// Ellipse Bounds
@@ -911,10 +920,7 @@ public class ReactViewBackgroundDrawable extends Drawable {
}
mInnerBottomLeftCorner.x = mInnerClipTempRectForBorderRadius.left;
mInnerBottomLeftCorner.y =
borderWidth.bottom != 0
? mInnerClipTempRectForBorderRadius.bottom * -2
: mInnerClipTempRectForBorderRadius.bottom;
mInnerBottomLeftCorner.y = mInnerClipTempRectForBorderRadius.bottom;
getEllipseIntersectionWithLine(
// Ellipse Bounds
@@ -940,7 +946,7 @@ public class ReactViewBackgroundDrawable extends Drawable {
}
mInnerTopRightCorner.x = mInnerClipTempRectForBorderRadius.right;
mInnerTopRightCorner.y = mInnerClipTempRectForBorderRadius.top * 2;
mInnerTopRightCorner.y = mInnerClipTempRectForBorderRadius.top;
getEllipseIntersectionWithLine(
// Ellipse Bounds
@@ -966,10 +972,7 @@ public class ReactViewBackgroundDrawable extends Drawable {
}
mInnerBottomRightCorner.x = mInnerClipTempRectForBorderRadius.right;
mInnerBottomRightCorner.y =
borderWidth.bottom != 0
? mInnerClipTempRectForBorderRadius.bottom * -2
: mInnerClipTempRectForBorderRadius.bottom;
mInnerBottomRightCorner.y = mInnerClipTempRectForBorderRadius.bottom;
getEllipseIntersectionWithLine(
// Ellipse Bounds
@@ -190,7 +190,6 @@ add_executable(reactnative_unittest
-fexceptions
-frtti
-std=c++17
-DANDROID
-DHERMES_ENABLE_DEBUGGER)
target_link_libraries(reactnative_unittest
@@ -47,6 +47,19 @@ Pod::Spec.new do |s|
s.dependency "RCTTypeSafety", version
s.dependency "ReactCommon/turbomodule/core", version
s.dependency "React-jsi", version
s.dependency "React-logger"
s.dependency "glog"
s.dependency "DoubleConversion"
s.dependency "React-Core"
s.dependency "React-debug"
s.dependency "React-utils"
s.dependency "React-runtimescheduler"
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
else
s.dependency "React-jsi"
end
s.subspec "animations" do |ss|
ss.dependency folly_dep_name, folly_version
@@ -232,14 +245,6 @@ Pod::Spec.new do |s|
end
end
s.subspec "debug_core" do |ss|
ss.dependency folly_dep_name, folly_version
ss.compiler_flags = folly_compiler_flags
ss.source_files = "react/debug/**/*.{m,mm,cpp,h}"
ss.exclude_files = "react/debug/tests"
ss.header_dir = "react/debug"
end
s.subspec "debug_renderer" do |ss|
ss.dependency folly_dep_name, folly_version
ss.compiler_flags = folly_compiler_flags
@@ -323,19 +328,4 @@ Pod::Spec.new do |s|
ss.header_dir = "react/renderer/leakchecker"
ss.pod_target_xcconfig = { "GCC_WARN_PEDANTIC" => "YES" }
end
s.subspec "runtimescheduler" do |ss|
ss.dependency folly_dep_name, folly_version
ss.compiler_flags = folly_compiler_flags
ss.source_files = "react/renderer/runtimescheduler/**/*.{cpp,h}"
ss.exclude_files = "react/renderer/runtimescheduler/tests"
ss.header_dir = "react/renderer/runtimescheduler"
ss.pod_target_xcconfig = { "GCC_WARN_PEDANTIC" => "YES" }
end
s.subspec "utils" do |ss|
ss.source_files = "react/utils/*.{m,mm,cpp,h}"
ss.header_dir = "react/utils"
end
end
@@ -70,8 +70,4 @@ Pod::Spec.new do |s|
sss.source_files = "react/nativemodule/core/ReactCommon/**/*.{cpp,h}"
end
end
s.subspec "react_debug_core" do |sss|
sss.source_files = "react/debug/*.{cpp,h}"
end
end
@@ -33,7 +33,7 @@ Pod::Spec.new do |s|
s.source_files = "*.{cpp,h}"
s.exclude_files = "SampleCxxModule.*"
s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\"",
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-runtimeexecutor/React_runtimeexecutor.framework/Headers\"",
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17" }
s.header_dir = "cxxreact"
@@ -18,7 +18,7 @@ constexpr struct {
int32_t Major = 0;
int32_t Minor = 72;
int32_t Patch = 0;
std::string_view Prerelease = "rc.3";
std::string_view Prerelease = "rc.6";
} ReactNativeVersion;
} // namespace facebook::react
@@ -0,0 +1,36 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
require "json"
package = JSON.parse(File.read(File.join(__dir__, "..", "..", "..", "package.json")))
version = package['version']
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
else
source[:tag] = "v#{version}"
end
Pod::Spec.new do |s|
s.name = "React-debug"
s.version = version
s.summary = "-" # TODO
s.homepage = "https://reactnative.dev/"
s.license = package["license"]
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = { :ios => min_ios_version_supported }
s.source = source
s.source_files = "**/*.{cpp,h}"
s.header_dir = "react/debug"
s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" }
if ENV['USE_FRAMEWORKS']
s.module_name = "React_debug"
s.header_mappings_dir = "../.."
end
end
@@ -134,8 +134,6 @@ AndroidTextInputProps::AndroidTextInputProps(
"selectionColor",
sourceProps.selectionColor,
{})),
selection(CoreFeatures::enablePropIteratorSetter? sourceProps.selection :
convertRawProp(context, rawProps, "selection", sourceProps.selection, {})),
value(CoreFeatures::enablePropIteratorSetter? sourceProps.value : convertRawProp(context, rawProps, "value", sourceProps.value, {})),
defaultValue(CoreFeatures::enablePropIteratorSetter? sourceProps.defaultValue : convertRawProp(context, rawProps,
"defaultValue",
@@ -349,7 +347,6 @@ void AndroidTextInputProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(placeholderTextColor);
RAW_SET_PROP_SWITCH_CASE_BASIC(secureTextEntry);
RAW_SET_PROP_SWITCH_CASE_BASIC(selectionColor);
RAW_SET_PROP_SWITCH_CASE_BASIC(selection);
RAW_SET_PROP_SWITCH_CASE_BASIC(defaultValue);
RAW_SET_PROP_SWITCH_CASE_BASIC(selectTextOnFocus);
RAW_SET_PROP_SWITCH_CASE_BASIC(submitBehavior);
@@ -449,7 +446,6 @@ folly::dynamic AndroidTextInputProps::getDynamic() const {
props["placeholderTextColor"] = toAndroidRepr(placeholderTextColor);
props["secureTextEntry"] = secureTextEntry;
props["selectionColor"] = toAndroidRepr(selectionColor);
props["selection"] = toDynamic(selection);
props["value"] = value;
props["defaultValue"] = defaultValue;
props["selectTextOnFocus"] = selectTextOnFocus;
@@ -27,32 +27,6 @@
namespace facebook {
namespace react {
struct AndroidTextInputSelectionStruct {
int start;
int end;
};
static inline void fromRawValue(
const PropsParserContext &context,
const RawValue &value,
AndroidTextInputSelectionStruct &result) {
auto map = (butter::map<std::string, RawValue>)value;
auto start = map.find("start");
if (start != map.end()) {
fromRawValue(context, start->second, result.start);
}
auto end = map.find("end");
if (end != map.end()) {
fromRawValue(context, end->second, result.end);
}
}
static inline std::string toString(
const AndroidTextInputSelectionStruct &value) {
return "[Object AndroidTextInputSelectionStruct]";
}
struct AndroidTextInputTextShadowOffsetStruct {
double width;
double height;
@@ -87,13 +61,6 @@ inline folly::dynamic toDynamic(
dynamicValue["height"] = value.height;
return dynamicValue;
}
inline folly::dynamic toDynamic(const AndroidTextInputSelectionStruct &value) {
folly::dynamic dynamicValue = folly::dynamic::object();
dynamicValue["start"] = value.start;
dynamicValue["end"] = value.end;
return dynamicValue;
}
#endif
class AndroidTextInputProps final : public ViewProps, public BaseTextProps {
@@ -138,7 +105,6 @@ class AndroidTextInputProps final : public ViewProps, public BaseTextProps {
SharedColor placeholderTextColor{};
bool secureTextEntry{false};
SharedColor selectionColor{};
AndroidTextInputSelectionStruct selection{};
std::string value{};
std::string defaultValue{};
bool selectTextOnFocus{false};
@@ -48,6 +48,8 @@ Pod::Spec.new do |s|
"\"$(PODS_ROOT)/DoubleConversion\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/React-utils/React_utils.framework/Headers\"",
]
end
@@ -61,4 +63,7 @@ Pod::Spec.new do |s|
s.dependency "React-Fabric"
s.dependency "React-Core/Default"
s.dependency "React-RCTImage"
s.dependency "React-debug"
s.dependency "React-utils"
s.dependency "glog"
end
@@ -0,0 +1,66 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
require "json"
package = JSON.parse(File.read(File.join(__dir__, "..", "..", "..", "..", "package.json")))
version = package['version']
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
else
source[:tag] = "v#{version}"
end
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
folly_version = '2021.07.22.00'
header_search_paths = [
"\"$(PODS_ROOT)/RCT-Folly\"",
]
if ENV['USE_FRAMEWORKS']
header_search_paths << "\"$(PODS_TARGET_SRCROOT)/../../..\"" #this is needed to allow the RuntimeScheduler access its own files
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\""
end
Pod::Spec.new do |s|
s.name = "React-runtimescheduler"
s.version = version
s.summary = "-" # TODO
s.homepage = "https://reactnative.dev/"
s.license = package["license"]
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = { :ios => min_ios_version_supported }
s.source = source
s.source_files = "**/*.{cpp,h}"
s.compiler_flags = folly_compiler_flags
s.header_dir = "react/renderer/runtimescheduler"
s.exclude_files = "tests"
s.pod_target_xcconfig = {
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
"HEADER_SEARCH_PATHS" => header_search_paths.join(' ')}
if ENV['USE_FRAMEWORKS']
s.module_name = "React_runtimescheduler"
s.header_mappings_dir = "../../.."
end
s.dependency "React-jsi"
s.dependency "React-runtimeexecutor"
s.dependency "React-callinvoker"
s.dependency "React-debug"
s.dependency "glog"
s.dependency "RCT-Folly", folly_version
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
else
s.dependency "React-jsi"
end
end
@@ -7,6 +7,7 @@
#include "RuntimeSchedulerBinding.h"
#include <ReactCommon/SchedulerPriority.h>
#include "RuntimeScheduler.h"
#include "SchedulerPriorityUtils.h"
#include "primitives.h"
@@ -78,7 +79,7 @@ jsi::Value RuntimeSchedulerBinding::get(
jsi::Runtime &runtime,
jsi::Value const &,
jsi::Value const *arguments,
size_t) noexcept -> jsi::Value {
size_t count) noexcept -> jsi::Value {
SchedulerPriority priority = fromRawValue(arguments[0].getNumber());
auto callback = arguments[1].getObject(runtime).getFunction(runtime);
@@ -8,11 +8,12 @@
#pragma once
#include <jsi/jsi.h>
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
namespace facebook {
namespace react {
class RuntimeScheduler;
/*
* Exposes RuntimeScheduler to JavaScript realm.
*/
@@ -8,6 +8,7 @@
#include "RuntimeSchedulerCallInvoker.h"
#include <utility>
#include "RuntimeScheduler.h"
namespace facebook::react {
@@ -8,11 +8,12 @@
#pragma once
#include <ReactCommon/CallInvoker.h>
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
namespace facebook {
namespace react {
class RuntimeScheduler;
/*
* Exposes RuntimeScheduler to native modules. All calls invoked on JavaScript
* queue from native modules will be funneled through RuntimeScheduler.
@@ -7,9 +7,7 @@
#pragma once
#include <folly/dynamic.h>
#include <jsi/jsi.h>
#include <react/renderer/core/CoreFeatures.h>
#include <react/renderer/runtimescheduler/Task.h>
namespace facebook {
@@ -24,14 +22,8 @@ struct TaskWrapper : public jsi::HostObject {
inline static jsi::Value valueFromTask(
jsi::Runtime &runtime,
std::shared_ptr<Task> task) {
if (CoreFeatures::useNativeState) {
jsi::Object obj(runtime);
obj.setNativeState(runtime, std::move(task));
return obj;
} else {
return jsi::Object::createFromHostObject(
runtime, std::make_shared<TaskWrapper>(task));
}
return jsi::Object::createFromHostObject(
runtime, std::make_shared<TaskWrapper>(task));
}
inline static std::shared_ptr<Task> taskFromValue(
@@ -41,11 +33,7 @@ inline static std::shared_ptr<Task> taskFromValue(
return nullptr;
}
if (CoreFeatures::useNativeState) {
return value.getObject(runtime).getNativeState<Task>(runtime);
} else {
return value.getObject(runtime).getHostObject<TaskWrapper>(runtime)->task;
}
return value.getObject(runtime).getHostObject<TaskWrapper>(runtime)->task;
}
} // namespace react
@@ -13,7 +13,7 @@
#include <react/renderer/componentregistry/ComponentDescriptorFactory.h>
#include <react/renderer/core/EventBeat.h>
#include <react/renderer/leakchecker/LeakChecker.h>
#include <react/renderer/runtimescheduler/RuntimeScheduler.h>
#include <react/renderer/uimanager/UIManagerCommitHook.h>
#include <react/renderer/uimanager/primitives.h>
#include <react/utils/ContextContainer.h>
@@ -0,0 +1,57 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
require "json"
package = JSON.parse(File.read(File.join(__dir__, "..", "..", "..", "package.json")))
version = package['version']
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
else
source[:tag] = "v#{version}"
end
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
folly_version = '2021.07.22.00'
header_search_paths = [
"\"$(PODS_ROOT)/RCT-Folly\"",
"\"$(PODS_TARGET_SRCROOT)\"",
"\"$(PODS_TARGET_SRCROOT)/ReactCommon\"",
]
if ENV["USE_FRAMEWORKS"]
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\""
end
Pod::Spec.new do |s|
s.name = "React-utils"
s.version = version
s.summary = "-" # TODO
s.homepage = "https://reactnative.dev/"
s.license = package["license"]
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = { :ios => min_ios_version_supported }
s.source = source
s.source_files = "**/*.{cpp,h,mm}"
s.compiler_flags = folly_compiler_flags
s.header_dir = "react/utils"
s.exclude_files = "tests"
s.pod_target_xcconfig = {
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
"HEADER_SEARCH_PATHS" => header_search_paths.join(' ')}
if ENV['USE_FRAMEWORKS']
s.module_name = "React_utils"
s.header_mappings_dir = "../.."
end
s.dependency "RCT-Folly", folly_version
s.dependency "React-debug"
s.dependency "glog"
end
+9 -9
View File
@@ -1,6 +1,6 @@
{
"name": "react-native",
"version": "0.72.0-rc.3",
"version": "0.72.0-rc.6",
"bin": "./cli.js",
"description": "A framework for building native apps using React",
"license": "MIT",
@@ -79,15 +79,15 @@
},
"dependencies": {
"@jest/create-cache-key-function": "^29.2.1",
"@react-native-community/cli": "11.2.3",
"@react-native-community/cli-platform-android": "11.2.3",
"@react-native-community/cli-platform-ios": "11.2.3",
"@react-native-community/cli": "11.3.2",
"@react-native-community/cli-platform-android": "11.3.2",
"@react-native-community/cli-platform-ios": "11.3.2",
"@react-native/assets-registry": "^0.72.0",
"@react-native/codegen": "^0.72.4",
"@react-native/gradle-plugin": "^0.72.7",
"@react-native/codegen": "^0.72.6",
"@react-native/gradle-plugin": "^0.72.10",
"@react-native/js-polyfills": "^0.72.1",
"@react-native/normalize-colors": "^0.72.0",
"@react-native/virtualized-lists": "^0.72.4",
"@react-native/virtualized-lists": "^0.72.5",
"abort-controller": "^3.0.0",
"anser": "^1.4.9",
"base64-js": "^1.1.2",
@@ -98,8 +98,8 @@
"jest-environment-node": "^29.2.1",
"jsc-android": "^250231.0.0",
"memoize-one": "^5.0.0",
"metro-runtime": "0.76.4",
"metro-source-map": "0.76.4",
"metro-runtime": "0.76.5",
"metro-source-map": "0.76.5",
"mkdirp": "^0.5.1",
"nullthrows": "^1.1.1",
"pretty-format": "^26.5.2",
@@ -550,6 +550,7 @@ class CodegenUtilsTests < Test::Unit::TestCase
].join(' ')
},
'dependencies': {
"DoubleConversion": [],
"FBReactNativeSpec": [],
"RCT-Folly": [],
"RCTRequired": [],
@@ -561,6 +562,7 @@ class CodegenUtilsTests < Test::Unit::TestCase
"ReactCommon/turbomodule/bridging": [],
"ReactCommon/turbomodule/core": [],
"hermes-engine": [],
"glog": [],
'React-NativeModulesApple': [],
}
}
@@ -573,7 +575,8 @@ class CodegenUtilsTests < Test::Unit::TestCase
'React-graphics': [],
'React-rncore': [],
'React-Fabric': [],
'React-utils': [],
'React-debug': [],
})
specs[:'script_phases'] = script_phases
@@ -585,11 +588,13 @@ class CodegenUtilsTests < Test::Unit::TestCase
specs = get_podspec_no_fabric_no_script()
specs["pod_target_xcconfig"]["FRAMEWORK_SEARCH_PATHS"].concat([])
specs["pod_target_xcconfig"]["HEADER_SEARCH_PATHS"].concat(" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_TARGET_SRCROOT)\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-Fabric/React_Fabric.framework/Headers\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-graphics/React_graphics.framework/Headers\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"$(PODS_CONFIGURATION_BUILD_DIR)/ReactCommon/ReactCommon.framework/Headers\" \"$(PODS_CONFIGURATION_BUILD_DIR)/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-NativeModulesApple/React_NativeModulesApple.framework/Headers\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-RCTFabric/RCTFabric.framework/Headers\"")
specs["pod_target_xcconfig"]["HEADER_SEARCH_PATHS"].concat(" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_TARGET_SRCROOT)\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-Fabric/React_Fabric.framework/Headers\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-graphics/React_graphics.framework/Headers\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"$(PODS_CONFIGURATION_BUILD_DIR)/ReactCommon/ReactCommon.framework/Headers\" \"$(PODS_CONFIGURATION_BUILD_DIR)/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-NativeModulesApple/React_NativeModulesApple.framework/Headers\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-RCTFabric/RCTFabric.framework/Headers\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-debug/React_debug.framework/Headers\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-utils/React_utils.framework/Headers\"")
specs[:dependencies].merge!({
'React-graphics': [],
'React-Fabric': [],
'React-utils': [],
'React-debug': [],
})
return specs
@@ -129,7 +129,7 @@ class NewArchitectureTests < Test::Unit::TestCase
# Assert
assert_equal(spec.compiler_flags, NewArchitectureHelper.folly_compiler_flags)
assert_equal(spec.pod_target_xcconfig["HEADER_SEARCH_PATHS"], "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\"")
assert_equal(spec.pod_target_xcconfig["HEADER_SEARCH_PATHS"], "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-utils/React_utils.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\"")
assert_equal(spec.pod_target_xcconfig["CLANG_CXX_LANGUAGE_STANDARD"], "c++17")
assert_equal(spec.pod_target_xcconfig["OTHER_CPLUSPLUSFLAGS"], "$(inherited) -DRCT_NEW_ARCH_ENABLED=1 -DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1")
assert_equal(
@@ -143,7 +143,13 @@ class NewArchitectureTests < Test::Unit::TestCase
{ :dependency_name => "RCTTypeSafety" },
{ :dependency_name => "ReactCommon/turbomodule/bridging" },
{ :dependency_name => "ReactCommon/turbomodule/core" },
{ :dependency_name => "React-NativeModulesApple" }
{ :dependency_name => "React-NativeModulesApple" },
{ :dependency_name => "Yoga" },
{ :dependency_name => "React-Fabric" },
{ :dependency_name => "React-graphics" },
{ :dependency_name => "React-utils" },
{ :dependency_name => "React-debug" },
{ :dependency_name => "hermes-engine" }
])
end
@@ -161,7 +167,7 @@ class NewArchitectureTests < Test::Unit::TestCase
# Assert
assert_equal(spec.compiler_flags, "-Wno-nullability-completeness #{NewArchitectureHelper.folly_compiler_flags}")
assert_equal(spec.pod_target_xcconfig["HEADER_SEARCH_PATHS"], "#{other_flags} \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\"")
assert_equal(spec.pod_target_xcconfig["HEADER_SEARCH_PATHS"], "#{other_flags} \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-utils/React_utils.framework/Headers\" \"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\"")
assert_equal(spec.pod_target_xcconfig["CLANG_CXX_LANGUAGE_STANDARD"], "c++17")
assert_equal(
spec.dependencies,
@@ -434,6 +434,60 @@ class UtilsTests < Test::Unit::TestCase
assert_equal(user_project_mock.save_invocation_count, 1)
end
# ================================= #
# Test - Apply Xcode 15 Patch #
# ================================= #
def test_applyXcode15Patch_correctlyAppliesNecessaryPatch
# Arrange
first_target = prepare_target("FirstTarget")
second_target = prepare_target("SecondTarget")
third_target = TargetMock.new("ThirdTarget", [
BuildConfigurationMock.new("Debug", {
"GCC_PREPROCESSOR_DEFINITIONS" => '$(inherited) "SomeFlag=1" '
}),
BuildConfigurationMock.new("Release", {
"GCC_PREPROCESSOR_DEFINITIONS" => '$(inherited) "SomeFlag=1" '
}),
], nil)
user_project_mock = UserProjectMock.new("a/path", [
prepare_config("Debug"),
prepare_config("Release"),
],
:native_targets => [
first_target,
second_target
]
)
pods_projects_mock = PodsProjectMock.new([], {"hermes-engine" => {}}, :native_targets => [
third_target
])
installer = InstallerMock.new(pods_projects_mock, [
AggregatedProjectMock.new(user_project_mock)
])
# Act
ReactNativePodsUtils.apply_xcode_15_patch(installer)
# Assert
first_target.build_configurations.each do |config|
assert_equal(config.build_settings["GCC_PREPROCESSOR_DEFINITIONS"].strip,
'$(inherited) "_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION"'
)
end
second_target.build_configurations.each do |config|
assert_equal(config.build_settings["GCC_PREPROCESSOR_DEFINITIONS"].strip,
'$(inherited) "_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION"'
)
end
third_target.build_configurations.each do |config|
assert_equal(config.build_settings["GCC_PREPROCESSOR_DEFINITIONS"].strip,
'$(inherited) "SomeFlag=1" "_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION"'
)
end
end
# ==================================== #
# Test - Set Node_Modules User Setting #
# ==================================== #
@@ -97,6 +97,8 @@ class CodegenUtils
"\"$(PODS_CONFIGURATION_BUILD_DIR)/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-NativeModulesApple/React_NativeModulesApple.framework/Headers\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-RCTFabric/RCTFabric.framework/Headers\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-debug/React_debug.framework/Headers\"",
"\"$(PODS_CONFIGURATION_BUILD_DIR)/React-utils/React_utils.framework/Headers\"",
])
end
@@ -128,6 +130,8 @@ class CodegenUtils
"ReactCommon/turbomodule/bridging": [],
"ReactCommon/turbomodule/core": [],
"React-NativeModulesApple": [],
"glog": [],
"DoubleConversion": [],
}
}
@@ -135,6 +139,8 @@ class CodegenUtils
spec[:'dependencies'].merge!({
'React-graphics': [],
'React-Fabric': [],
'React-debug': [],
'React-utils': [],
});
end
@@ -96,6 +96,8 @@ class NewArchitectureHelper
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers/react/nativemodule/core\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-RCTFabric/RCTFabric.framework/Headers\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-utils/React_utils.framework/Headers\""
header_search_paths << "\"${PODS_CONFIGURATION_BUILD_DIR}/React-debug/React_debug.framework/Headers\""
end
header_search_paths_string = header_search_paths.join(" ")
spec.compiler_flags = compiler_flags.empty? ? @@folly_compiler_flags : "#{compiler_flags} #{@@folly_compiler_flags}"
@@ -118,6 +120,17 @@ class NewArchitectureHelper
spec.dependency "ReactCommon/turbomodule/bridging"
spec.dependency "ReactCommon/turbomodule/core"
spec.dependency "React-NativeModulesApple"
spec.dependency "Yoga"
spec.dependency "React-Fabric"
spec.dependency "React-graphics"
spec.dependency "React-utils"
spec.dependency "React-debug"
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
spec.dependency "hermes-engine"
else
spec.dependency "React-jsi"
end
end
spec.pod_target_xcconfig = current_config
@@ -121,6 +121,18 @@ class ReactNativePodsUtils
end
end
def self.apply_xcode_15_patch(installer)
installer.target_installation_results.pod_target_installation_results
.each do |pod_name, target_installation_result|
target_installation_result.native_target.build_configurations.each do |config|
# unary_function and binary_function are no longer provided in C++17 and newer standard modes as part of Xcode 15. They can be re-enabled with setting _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION
# Ref: https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes#Deprecations
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= '$(inherited) '
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << '"_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION" '
end
end
end
def self.apply_flags_for_fabric(installer, fabric_enabled: false)
fabric_flag = "-DRN_FABRIC_ENABLED"
if fabric_enabled
@@ -176,7 +176,7 @@ else
if [[ $EMIT_SOURCEMAP == true ]]; then
EXTRA_COMPILER_ARGS="$EXTRA_COMPILER_ARGS -output-source-map"
fi
"$HERMES_CLI_PATH" -emit-binary $EXTRA_COMPILER_ARGS -out "$DEST/main.jsbundle" "$BUNDLE_FILE"
"$HERMES_CLI_PATH" -emit-binary -max-diagnostic-width=80 "$EXTRA_COMPILER_ARGS" -out "$DEST/main.jsbundle" "$BUNDLE_FILE"
if [[ $EMIT_SOURCEMAP == true ]]; then
HBC_SOURCEMAP_FILE="$DEST/main.jsbundle.map"
"$NODE_BINARY" "$COMPOSE_SOURCEMAP_PATH" "$PACKAGER_SOURCEMAP_FILE" "$HBC_SOURCEMAP_FILE" -o "$SOURCEMAP_FILE"
@@ -117,6 +117,8 @@ def use_react_native! (
pod 'React-Core/RCTWebSocket', :path => "#{prefix}/"
pod 'React-rncore', :path => "#{prefix}/ReactCommon"
pod 'React-cxxreact', :path => "#{prefix}/ReactCommon/cxxreact"
pod 'React-debug', :path => "#{prefix}/ReactCommon/react/debug"
pod 'React-utils', :path => "#{prefix}/ReactCommon/react/utils"
if hermes_enabled
setup_hermes!(:react_native_path => prefix, :fabric_enabled => fabric_enabled)
@@ -129,6 +131,7 @@ def use_react_native! (
pod 'React-callinvoker', :path => "#{prefix}/ReactCommon/callinvoker"
pod 'React-runtimeexecutor', :path => "#{prefix}/ReactCommon/runtimeexecutor"
pod 'React-runtimescheduler', :path => "#{prefix}/ReactCommon/react/renderer/runtimescheduler"
pod 'React-perflogger', :path => "#{prefix}/ReactCommon/reactperflogger"
pod 'React-logger', :path => "#{prefix}/ReactCommon/logger"
pod 'ReactCommon/turbomodule/core', :path => "#{prefix}/ReactCommon", :modular_headers => true
@@ -241,6 +244,7 @@ def react_native_post_install(
ReactNativePodsUtils.update_search_paths(installer)
ReactNativePodsUtils.set_node_modules_user_settings(installer, react_native_path)
ReactNativePodsUtils.apply_flags_for_fabric(installer, fabric_enabled: fabric_enabled)
ReactNativePodsUtils.apply_xcode_15_patch(installer)
NewArchitectureHelper.set_clang_cxx_language_standard_if_needed(installer)
is_new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == "1"
@@ -1,10 +1,3 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
apply plugin: "com.android.application"
apply plugin: "com.facebook.react"
+1 -1
View File
@@ -51,7 +51,7 @@ target 'HelloWorld' do
end
post_install do |installer|
# https://github.com/facebook/react-native/blob/main/scripts/react_native_pods.rb#L197-L202
# https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
react_native_post_install(
installer,
config[:reactNativePath],
+5 -5
View File
@@ -11,14 +11,14 @@
},
"dependencies": {
"react": "18.2.0",
"react-native": "0.72.0-rc.3"
"react-native": "0.72.0-rc.6"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.12.5",
"@react-native/eslint-config": "^0.72.1",
"@react-native/metro-config": "^0.72.5",
"@babel/runtime": "^7.20.0",
"@react-native/eslint-config": "^0.72.2",
"@react-native/metro-config": "^0.72.6",
"@tsconfig/react-native": "^3.0.0",
"@types/metro-config": "^0.76.3",
"@types/react": "^18.0.24",
@@ -26,7 +26,7 @@
"babel-jest": "^29.2.1",
"eslint": "^8.19.0",
"jest": "^29.2.1",
"metro-react-native-babel-preset": "0.76.4",
"metro-react-native-babel-preset": "0.76.5",
"prettier": "^2.4.1",
"react-test-renderer": "18.2.0",
"typescript": "4.8.4"
+101
View File
@@ -0,0 +1,101 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
/**
* These are types for things that are present for New Architecture enabled apps
* which is currently considered experimental.
*
* To load the types declared here in an actual project, there are three ways.
*
* 1. If your `tsconfig.json` already has a `"types"` array in the `"compilerOptions"` section,
* is to add `"react-native/types/experimental"` to the `"types"` array.
*
* 2. Alternatively, a specific import syntax can to be used from a typescript file.
* This module does not exist in reality, which is why the {} is important:
*
* ```ts
* import {} from 'react-native/types/experimental'
* ```
*
* 3. It is also possible to include it through a triple-slash reference:
*
* ```ts
* /// <reference types="react-native/types/experimental" />
* ```
*
* Either the import or the reference only needs to appear once, anywhere in the project.
*/
import {DimensionValue} from 'react-native/Libraries/StyleSheet/StyleSheetTypes';
export {};
declare module '.' {
export interface FlexStyle {
/**
* Equivalent to `marginVertical`
*/
marginBlock?: DimensionValue | undefined;
/**
* Equivalent to `marginBottom`
*/
marginBlockEnd?: DimensionValue | undefined;
/**
* Equivalent to `marginTop`
*/
marginBlockStart?: DimensionValue | undefined;
/**
* Equivalent to `marginHorizontal`
*/
marginInline?: DimensionValue | undefined;
/**
* Equivalent to `marginEnd`
*/
marginInlineEnd?: DimensionValue | undefined;
/**
* Equivalent to `marginStart`
*/
marginInlineStart?: DimensionValue | undefined;
/**
* Equivalent to `paddingVertical`
*/
paddingBlock?: DimensionValue | undefined;
/**
* Equivalent to `paddingBottom`
*/
paddingBlockEnd?: DimensionValue | undefined;
/**
* Equivalent to `paddingTop`
*/
paddingBlockStart?: DimensionValue | undefined;
/**
* Equivalent to `paddingHorizontal`
*/
paddingInline?: DimensionValue | undefined;
/**
* Equivalent to `paddingEnd`
*/
paddingInlineEnd?: DimensionValue | undefined;
/**
* Equivalent to `paddingStart`
*/
paddingInlineStart?: DimensionValue | undefined;
}
}
File diff suppressed because it is too large Load Diff
+15 -6
View File
@@ -41,6 +41,10 @@
#import <React/RCTLocalAssetImageLoader.h>
#import <React/RCTNetworking.h>
#import <React/RCTRootView.h>
#import <React/RCTRuntimeExecutorFromBridge.h>
#import <ReactCommon/RuntimeExecutor.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>
#import <cxxreact/JSExecutor.h>
@@ -55,8 +59,6 @@
#import <React/RCTLegacyViewManagerInteropComponentView.h>
#import <react/config/ReactNativeConfig.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>
#import <react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h>
#endif
@@ -75,12 +77,19 @@
#import <ReactCommon/RCTTurboModuleManager.h>
#import "RNTesterTurboModuleProvider.h"
@interface RCTBridge ()
- (std::shared_ptr<facebook::react::MessageQueueThread>)jsMessageThread;
- (void)invokeAsync:(std::function<void()> &&)func;
@end
using namespace facebook::react;
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
#ifdef RN_FABRIC_ENABLED
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
facebook::react::ContextContainer::Shared _contextContainer;
std::shared_ptr<facebook::react::RuntimeScheduler> _runtimeScheduler;
#endif
RCTTurboModuleManager *_turboModuleManager;
@@ -200,9 +209,9 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
std::shared_ptr<facebook::react::CallInvoker> callInvoker = bridge.jsCallInvoker;
_runtimeScheduler = std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
#ifdef RN_FABRIC_ENABLED
_runtimeScheduler = std::make_shared<facebook::react::RuntimeScheduler>(RCTRuntimeExecutorFromBridge(bridge));
_contextContainer->erase("RuntimeScheduler");
_contextContainer->insert("RuntimeScheduler", _runtimeScheduler);
callInvoker = std::make_shared<facebook::react::RuntimeSchedulerCallInvoker>(_runtimeScheduler);
@@ -230,11 +239,11 @@ static NSString *const kRNConcurrentRoot = @"concurrentRoot";
return;
}
__typeof(self) strongSelf = weakSelf;
#if RN_FABRIC_ENABLED
if (strongSelf && strongSelf->_runtimeScheduler) {
facebook::react::RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime, strongSelf->_runtimeScheduler);
}
#endif
if (strongSelf) {
facebook::react::RuntimeExecutor syncRuntimeExecutor =
[&](std::function<void(facebook::jsi::Runtime & runtime_)> &&callback) { callback(runtime); };
@@ -13,6 +13,7 @@
const React = require('react');
const {
ActivityIndicator,
Animated,
Image,
Platform,
@@ -33,16 +34,28 @@ export type Item = {
...
};
function genItemData(count: number, start: number = 0): Array<Item> {
function genItemData(i: number): Item {
const itemHash = Math.abs(hashCode('Item ' + i));
return {
title: 'Item ' + i,
text: LOREM_IPSUM.substr(0, (itemHash % 301) + 20),
key: String(i),
pressed: false,
};
}
function genNewerItems(count: number, start: number = 0): Array<Item> {
const dataBlob = [];
for (let ii = start; ii < count + start; ii++) {
const itemHash = Math.abs(hashCode('Item ' + ii));
dataBlob.push({
title: 'Item ' + ii,
text: LOREM_IPSUM.substr(0, (itemHash % 301) + 20),
key: String(ii),
pressed: false,
});
for (let i = start; i < count + start; i++) {
dataBlob.push(genItemData(i));
}
return dataBlob;
}
function genOlderItems(count: number, start: number = 0): Array<Item> {
const dataBlob = [];
for (let i = count; i > 0; i--) {
dataBlob.push(genItemData(start - i));
}
return dataBlob;
}
@@ -147,6 +160,12 @@ class SeparatorComponent extends React.PureComponent<{...}> {
}
}
const LoadingComponent: React.ComponentType<{}> = React.memo(() => (
<View style={styles.loadingContainer}>
<ActivityIndicator />
</View>
));
class ItemSeparatorComponent extends React.PureComponent<$FlowFixMeProps> {
render(): React.Node {
const style = this.props.highlighted
@@ -352,6 +371,13 @@ const styles = StyleSheet.create({
text: {
flex: 1,
},
loadingContainer: {
alignItems: 'center',
justifyContent: 'center',
height: 100,
borderTopWidth: 1,
borderTopColor: 'rgb(200, 199, 204)',
},
});
module.exports = {
@@ -362,8 +388,10 @@ module.exports = {
ItemSeparatorComponent,
PlainInput,
SeparatorComponent,
LoadingComponent,
Spindicator,
genItemData,
genNewerItems,
genOlderItems,
getItemLayout,
pressItem,
renderSmallSwitchOption,
@@ -35,8 +35,10 @@ import {
ItemSeparatorComponent,
PlainInput,
SeparatorComponent,
LoadingComponent,
Spindicator,
genItemData,
genNewerItems,
genOlderItems,
getItemLayout,
pressItem,
renderSmallSwitchOption,
@@ -44,6 +46,11 @@ import {
import type {Item} from '../../components/ListExampleShared';
const PAGE_SIZE = 100;
const NUM_PAGES = 10;
const INITIAL_PAGE_OFFSET = Math.floor(NUM_PAGES / 2);
const LOAD_TIME = 2000;
const VIEWABILITY_CONFIG = {
minimumViewTime: 3000,
viewAreaCoveragePercentThreshold: 100,
@@ -53,6 +60,8 @@ const VIEWABILITY_CONFIG = {
type Props = $ReadOnly<{||}>;
type State = {|
data: Array<Item>,
first: number,
last: number,
debug: boolean,
horizontal: boolean,
inverted: boolean,
@@ -66,13 +75,18 @@ type State = {|
onPressDisabled: boolean,
textSelectable: boolean,
isRTL: boolean,
maintainVisibleContentPosition: boolean,
previousLoading: boolean,
nextLoading: boolean,
|};
const IS_RTL = I18nManager.isRTL;
class FlatListExample extends React.PureComponent<Props, State> {
state: State = {
data: genItemData(100),
data: genNewerItems(PAGE_SIZE, PAGE_SIZE * INITIAL_PAGE_OFFSET),
first: PAGE_SIZE * INITIAL_PAGE_OFFSET,
last: PAGE_SIZE + PAGE_SIZE * INITIAL_PAGE_OFFSET,
debug: false,
horizontal: false,
inverted: false,
@@ -86,6 +100,9 @@ class FlatListExample extends React.PureComponent<Props, State> {
onPressDisabled: false,
textSelectable: true,
isRTL: IS_RTL,
maintainVisibleContentPosition: true,
previousLoading: false,
nextLoading: false,
};
/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
@@ -209,6 +226,11 @@ class FlatListExample extends React.PureComponent<Props, State> {
this.state.isRTL,
this._setIsRTL,
)}
{renderSmallSwitchOption(
'Maintain content position',
this.state.maintainVisibleContentPosition,
this._setBooleanValue('maintainVisibleContentPosition'),
)}
{Platform.OS === 'android' && (
<View>
<TextInput
@@ -230,8 +252,12 @@ class FlatListExample extends React.PureComponent<Props, State> {
<Animated.FlatList
fadingEdgeLength={this.state.fadingEdgeLength}
ItemSeparatorComponent={ItemSeparatorComponent}
ListHeaderComponent={<HeaderComponent />}
ListFooterComponent={FooterComponent}
ListHeaderComponent={
this.state.previousLoading ? LoadingComponent : HeaderComponent
}
ListFooterComponent={
this.state.nextLoading ? LoadingComponent : FooterComponent
}
ListEmptyComponent={ListEmptyComponent}
// $FlowFixMe[missing-empty-array-annot]
data={this.state.empty ? [] : filteredData}
@@ -250,6 +276,8 @@ class FlatListExample extends React.PureComponent<Props, State> {
keyboardShouldPersistTaps="always"
keyboardDismissMode="on-drag"
numColumns={1}
onStartReached={this._onStartReached}
initialScrollIndex={Math.floor(PAGE_SIZE / 2)}
onEndReached={this._onEndReached}
onRefresh={this._onRefresh}
onScroll={
@@ -260,6 +288,11 @@ class FlatListExample extends React.PureComponent<Props, State> {
refreshing={false}
contentContainerStyle={styles.list}
viewabilityConfig={VIEWABILITY_CONFIG}
maintainVisibleContentPosition={
this.state.maintainVisibleContentPosition
? {minIndexForVisible: 0}
: undefined
}
{...flatListItemRendererProps}
/>
</View>
@@ -280,13 +313,33 @@ class FlatListExample extends React.PureComponent<Props, State> {
_getItemLayout = (data: any, index: number) => {
return getItemLayout(data, index, this.state.horizontal);
};
_onEndReached = () => {
if (this.state.data.length >= 1000) {
_onStartReached = () => {
if (this.state.first <= 0 || this.state.previousLoading) {
return;
}
this.setState(state => ({
data: state.data.concat(genItemData(100, state.data.length)),
}));
this.setState({previousLoading: true});
setTimeout(() => {
this.setState(state => ({
previousLoading: false,
data: genOlderItems(PAGE_SIZE, state.first).concat(state.data),
first: state.first - PAGE_SIZE,
}));
}, LOAD_TIME);
};
_onEndReached = () => {
if (this.state.last >= PAGE_SIZE * NUM_PAGES || this.state.nextLoading) {
return;
}
this.setState({nextLoading: true});
setTimeout(() => {
this.setState(state => ({
nextLoading: false,
data: state.data.concat(genNewerItems(PAGE_SIZE, state.last)),
last: state.last + PAGE_SIZE,
}));
}, LOAD_TIME);
};
// $FlowFixMe[missing-local-annot]
_onPressCallback = () => {
@@ -343,7 +396,7 @@ class FlatListExample extends React.PureComponent<Props, State> {
_pressItem = (key: string) => {
this._listRef?.recordInteraction();
const index = Number(key);
const index = this.state.data.findIndex(item => item.key === key);
const itemState = pressItem(this.state.data[index]);
this.setState(state => ({
...state,
@@ -23,7 +23,7 @@ const {
ItemComponent,
PlainInput,
SeparatorComponent,
genItemData,
genNewerItems,
getItemLayout,
pressItem,
renderSmallSwitchOption,
@@ -46,7 +46,7 @@ class MultiColumnExample extends React.PureComponent<
numColumns: number,
virtualized: boolean,
|} = {
data: genItemData(1000),
data: genNewerItems(1000),
filterText: '',
fixedHeight: true,
logViewable: false,
@@ -22,7 +22,7 @@ const {
PlainInput,
SeparatorComponent,
Spindicator,
genItemData,
genNewerItems,
pressItem,
renderSmallSwitchOption,
renderStackedItem,
@@ -170,7 +170,7 @@ export function SectionList_scrollable(Props: {
const [logViewable, setLogViewable] = React.useState(false);
const [debug, setDebug] = React.useState(false);
const [inverted, setInverted] = React.useState(false);
const [data, setData] = React.useState(genItemData(1000));
const [data, setData] = React.useState(genNewerItems(1000));
const filterRegex = new RegExp(String(filterText), 'i');
const filter = (item: Item) =>
@@ -73,6 +73,10 @@ type ViewabilityHelperCallbackTuple = {
type State = {
renderMask: CellRenderMask,
cellsAroundViewport: {first: number, last: number},
// Used to track items added at the start of the list for maintainVisibleContentPosition.
firstVisibleItemKey: ?string,
// When > 0 the scroll position available in JS is considered stale and should not be used.
pendingScrollUpdateCount: number,
};
/**
@@ -448,9 +452,24 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
const initialRenderRegion = VirtualizedList._initialRenderRegion(props);
const minIndexForVisible =
this.props.maintainVisibleContentPosition?.minIndexForVisible ?? 0;
this.state = {
cellsAroundViewport: initialRenderRegion,
renderMask: VirtualizedList._createRenderMask(props, initialRenderRegion),
firstVisibleItemKey:
this.props.getItemCount(this.props.data) > minIndexForVisible
? VirtualizedList._getItemKey(this.props, minIndexForVisible)
: null,
// When we have a non-zero initialScrollIndex, we will receive a
// scroll event later so this will prevent the window from updating
// until we get a valid offset.
pendingScrollUpdateCount:
this.props.initialScrollIndex != null &&
this.props.initialScrollIndex > 0
? 1
: 0,
};
}
@@ -502,6 +521,40 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
}
}
static _findItemIndexWithKey(
props: Props,
key: string,
hint: ?number,
): ?number {
const itemCount = props.getItemCount(props.data);
if (hint != null && hint >= 0 && hint < itemCount) {
const curKey = VirtualizedList._getItemKey(props, hint);
if (curKey === key) {
return hint;
}
}
for (let ii = 0; ii < itemCount; ii++) {
const curKey = VirtualizedList._getItemKey(props, ii);
if (curKey === key) {
return ii;
}
}
return null;
}
static _getItemKey(
props: {
data: Props['data'],
getItem: Props['getItem'],
keyExtractor: Props['keyExtractor'],
...
},
index: number,
): string {
const item = props.getItem(props.data, index);
return VirtualizedList._keyExtractor(item, index, props);
}
static _createRenderMask(
props: Props,
cellsAroundViewport: {first: number, last: number},
@@ -585,6 +638,7 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
_adjustCellsAroundViewport(
props: Props,
cellsAroundViewport: {first: number, last: number},
pendingScrollUpdateCount: number,
): {first: number, last: number} {
const {data, getItemCount} = props;
const onEndReachedThreshold = onEndReachedThresholdOrDefault(
@@ -616,21 +670,9 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
),
};
} else {
// If we have a non-zero initialScrollIndex and run this before we've scrolled,
// we'll wipe out the initialNumToRender rendered elements starting at initialScrollIndex.
// So let's wait until we've scrolled the view to the right place. And until then,
// we will trust the initialScrollIndex suggestion.
// Thus, we want to recalculate the windowed render limits if any of the following hold:
// - initialScrollIndex is undefined or is 0
// - initialScrollIndex > 0 AND scrolling is complete
// - initialScrollIndex > 0 AND the end of the list is visible (this handles the case
// where the list is shorter than the visible area)
if (
props.initialScrollIndex &&
!this._scrollMetrics.offset &&
Math.abs(distanceFromEnd) >= Number.EPSILON
) {
// If we have a pending scroll update, we should not adjust the render window as it
// might override the correct window.
if (pendingScrollUpdateCount > 0) {
return cellsAroundViewport.last >= getItemCount(data)
? VirtualizedList._constrainToItemCount(cellsAroundViewport, props)
: cellsAroundViewport;
@@ -712,14 +754,59 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
return prevState;
}
let maintainVisibleContentPositionAdjustment: ?number = null;
const prevFirstVisibleItemKey = prevState.firstVisibleItemKey;
const minIndexForVisible =
newProps.maintainVisibleContentPosition?.minIndexForVisible ?? 0;
const newFirstVisibleItemKey =
newProps.getItemCount(newProps.data) > minIndexForVisible
? VirtualizedList._getItemKey(newProps, minIndexForVisible)
: null;
if (
newProps.maintainVisibleContentPosition != null &&
prevFirstVisibleItemKey != null &&
newFirstVisibleItemKey != null
) {
if (newFirstVisibleItemKey !== prevFirstVisibleItemKey) {
// Fast path if items were added at the start of the list.
const hint =
itemCount - prevState.renderMask.numCells() + minIndexForVisible;
const firstVisibleItemIndex = VirtualizedList._findItemIndexWithKey(
newProps,
prevFirstVisibleItemKey,
hint,
);
maintainVisibleContentPositionAdjustment =
firstVisibleItemIndex != null
? firstVisibleItemIndex - minIndexForVisible
: null;
} else {
maintainVisibleContentPositionAdjustment = null;
}
}
const constrainedCells = VirtualizedList._constrainToItemCount(
prevState.cellsAroundViewport,
maintainVisibleContentPositionAdjustment != null
? {
first:
prevState.cellsAroundViewport.first +
maintainVisibleContentPositionAdjustment,
last:
prevState.cellsAroundViewport.last +
maintainVisibleContentPositionAdjustment,
}
: prevState.cellsAroundViewport,
newProps,
);
return {
cellsAroundViewport: constrainedCells,
renderMask: VirtualizedList._createRenderMask(newProps, constrainedCells),
firstVisibleItemKey: newFirstVisibleItemKey,
pendingScrollUpdateCount:
maintainVisibleContentPositionAdjustment != null
? prevState.pendingScrollUpdateCount + 1
: prevState.pendingScrollUpdateCount,
};
}
@@ -751,7 +838,7 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
for (let ii = first; ii <= last; ii++) {
const item = getItem(data, ii);
const key = this._keyExtractor(item, ii, this.props);
const key = VirtualizedList._keyExtractor(item, ii, this.props);
this._indicesToKeys.set(ii, key);
if (stickyIndicesFromProps.has(ii + stickyOffset)) {
@@ -824,15 +911,14 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
_getSpacerKey = (isVertical: boolean): string =>
isVertical ? 'height' : 'width';
_keyExtractor(
static _keyExtractor(
item: Item,
index: number,
props: {
keyExtractor?: ?(item: Item, index: number) => string,
...
},
// $FlowFixMe[missing-local-annot]
) {
): string {
if (props.keyExtractor != null) {
return props.keyExtractor(item, index);
}
@@ -878,6 +964,10 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
cellKey={this._getCellKey() + '-header'}
key="$header">
<View
// We expect that header component will be a single native view so make it
// not collapsable to avoid this view being flattened and make this assumption
// no longer true.
collapsable={false}
onLayout={this._onLayoutHeader}
style={StyleSheet.compose(
inversionStyle,
@@ -1035,6 +1125,16 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
style: inversionStyle
? [inversionStyle, this.props.style]
: this.props.style,
maintainVisibleContentPosition:
this.props.maintainVisibleContentPosition != null
? {
...this.props.maintainVisibleContentPosition,
// Adjust index to account for ListHeaderComponent.
minIndexForVisible:
this.props.maintainVisibleContentPosition.minIndexForVisible +
(this.props.ListHeaderComponent ? 1 : 0),
}
: undefined,
};
this._hasMore = this.state.cellsAroundViewport.last < itemCount - 1;
@@ -1456,8 +1556,13 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
onStartReachedThreshold,
onEndReached,
onEndReachedThreshold,
initialScrollIndex,
} = this.props;
// If we have any pending scroll updates it means that the scroll metrics
// are out of date and we should not call any of the edge reached callbacks.
if (this.state.pendingScrollUpdateCount > 0) {
return;
}
const {contentLength, visibleLength, offset} = this._scrollMetrics;
let distanceFromStart = offset;
let distanceFromEnd = contentLength - visibleLength - offset;
@@ -1509,14 +1614,8 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
isWithinStartThreshold &&
this._scrollMetrics.contentLength !== this._sentStartForContentLength
) {
// On initial mount when using initialScrollIndex the offset will be 0 initially
// and will trigger an unexpected onStartReached. To avoid this we can use
// timestamp to differentiate between the initial scroll metrics and when we actually
// received the first scroll event.
if (!initialScrollIndex || this._scrollMetrics.timestamp !== 0) {
this._sentStartForContentLength = this._scrollMetrics.contentLength;
onStartReached({distanceFromStart});
}
this._sentStartForContentLength = this._scrollMetrics.contentLength;
onStartReached({distanceFromStart});
}
// If the user scrolls away from the start or end and back again,
@@ -1643,6 +1742,11 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
visibleLength,
zoomScale,
};
if (this.state.pendingScrollUpdateCount > 0) {
this.setState(state => ({
pendingScrollUpdateCount: state.pendingScrollUpdateCount - 1,
}));
}
this._updateViewableItems(this.props, this.state.cellsAroundViewport);
if (!this.props) {
return;
@@ -1758,6 +1862,7 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
const cellsAroundViewport = this._adjustCellsAroundViewport(
props,
state.cellsAroundViewport,
state.pendingScrollUpdateCount,
);
const renderMask = VirtualizedList._createRenderMask(
props,
@@ -1788,7 +1893,7 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
return {
index,
item,
key: this._keyExtractor(item, index, props),
key: VirtualizedList._keyExtractor(item, index, props),
isViewable,
};
};
@@ -1849,13 +1954,12 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
inLayout?: boolean,
...
} => {
const {data, getItem, getItemCount, getItemLayout} = props;
const {data, getItemCount, getItemLayout} = props;
invariant(
index >= 0 && index < getItemCount(data),
'Tried to get frame for out of range index ' + index,
);
const item = getItem(data, index);
const frame = this._frames[this._keyExtractor(item, index, props)];
const frame = this._frames[VirtualizedList._getItemKey(props, index)];
if (!frame || frame.index !== index) {
if (getItemLayout) {
/* $FlowFixMe[prop-missing] (>=0.63.0 site=react_native_fb) This comment
@@ -1890,11 +1994,8 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
// where it is.
if (
focusedCellIndex >= itemCount ||
this._keyExtractor(
props.getItem(props.data, focusedCellIndex),
focusedCellIndex,
props,
) !== this._lastFocusedCellKey
VirtualizedList._getItemKey(props, focusedCellIndex) !==
this._lastFocusedCellKey
) {
return [];
}
@@ -1935,6 +2036,11 @@ class VirtualizedList extends StateSafePureComponent<Props, State> {
props: FrameMetricProps,
cellsAroundViewport: {first: number, last: number},
) {
// If we have any pending scroll updates it means that the scroll metrics
// are out of date and we should not call any of the visibility callbacks.
if (this.state.pendingScrollUpdateCount > 0) {
return;
}
this._viewabilityTuples.forEach(tuple => {
tuple.viewabilityHelper.onUpdate(
props,
@@ -2164,10 +2164,70 @@ it('virtualizes away last focused index if item removed', () => {
expect(component).toMatchSnapshot();
});
function generateItems(count) {
it('handles maintainVisibleContentPosition', () => {
const items = generateItems(20);
const ITEM_HEIGHT = 10;
let component;
ReactTestRenderer.act(() => {
component = ReactTestRenderer.create(
<VirtualizedList
initialNumToRender={1}
windowSize={1}
maintainVisibleContentPosition={{minIndexForVisible: 0}}
{...baseItemProps(items)}
{...fixedHeightItemLayoutProps(ITEM_HEIGHT)}
/>,
);
});
ReactTestRenderer.act(() => {
simulateLayout(component, {
viewport: {width: 10, height: 50},
content: {width: 10, height: items.length * ITEM_HEIGHT},
});
performAllBatches();
});
// Initial render.
expect(component).toMatchSnapshot();
// Add new items at the start of the list to trigger the maintainVisibleContentPosition adjustment.
const newItems = [...generateItems(10, items.length), ...items];
ReactTestRenderer.act(() => {
component.update(
<VirtualizedList
initialNumToRender={1}
windowSize={1}
maintainVisibleContentPosition={{minIndexForVisible: 0}}
{...baseItemProps(newItems)}
{...fixedHeightItemLayoutProps(ITEM_HEIGHT)}
/>,
);
});
// Previously rendered cells should be rendered still.
expect(component).toMatchSnapshot();
// Simulate scroll adjustment from native maintainVisibleContentPosition.
ReactTestRenderer.act(() => {
simulateContentLayout(component, {
width: 10,
height: newItems.length * ITEM_HEIGHT,
});
simulateScroll(component, {x: 0, y: 10 * ITEM_HEIGHT});
performAllBatches();
});
// Previously rendered cells should be rendered still + starting to render new cells ahead.
expect(component).toMatchSnapshot();
});
function generateItems(count, startKey = 0) {
return Array(count)
.fill()
.map((_, i) => ({key: i}));
.map((_, i) => ({key: i + startKey}));
}
function generateItemsStickyEveryN(count, n) {
@@ -2225,7 +2285,7 @@ function simulateContentLayout(component, dimensions) {
function simulateCellLayout(component, items, itemIndex, dimensions) {
const instance = component.getInstance();
const cellKey = instance._keyExtractor(
const cellKey = VirtualizedList._keyExtractor(
items[itemIndex],
itemIndex,
instance.props,
@@ -65,6 +65,7 @@ exports[`VirtualizedList forwards correct stickyHeaderIndices when ListHeaderCom
>
<View>
<View
collapsable={false}
onLayout={[Function]}
>
<Header />
@@ -1048,6 +1049,7 @@ exports[`VirtualizedList renders all the bells and whistles 1`] = `
<RCTRefreshControl />
<View>
<View
collapsable={false}
onLayout={[Function]}
style={
Object {
@@ -1249,6 +1251,7 @@ exports[`VirtualizedList renders empty list with empty component 1`] = `
>
<View>
<View
collapsable={false}
onLayout={[Function]}
>
<header />
@@ -1834,45 +1837,12 @@ exports[`adjusts render area with non-zero initialScrollIndex 1`] = `
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={15}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={16}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={17}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={18}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={19}
/>
</View>
style={
Object {
"height": 50,
}
}
/>
</View>
</RCTScrollView>
`;
@@ -3121,10 +3091,566 @@ exports[`gracefully handles negative initialScrollIndex 1`] = `
value={3}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={4}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={5}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={6}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={7}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={8}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={9}
/>
</View>
</View>
</RCTScrollView>
`;
exports[`handles maintainVisibleContentPosition 1`] = `
<RCTScrollView
data={
Array [
Object {
"key": 0,
},
Object {
"key": 1,
},
Object {
"key": 2,
},
Object {
"key": 3,
},
Object {
"key": 4,
},
Object {
"key": 5,
},
Object {
"key": 6,
},
Object {
"key": 7,
},
Object {
"key": 8,
},
Object {
"key": 9,
},
Object {
"key": 10,
},
Object {
"key": 11,
},
Object {
"key": 12,
},
Object {
"key": 13,
},
Object {
"key": 14,
},
Object {
"key": 15,
},
Object {
"key": 16,
},
Object {
"key": 17,
},
Object {
"key": 18,
},
Object {
"key": 19,
},
]
}
getItem={[Function]}
getItemCount={[Function]}
getItemLayout={[Function]}
initialNumToRender={1}
maintainVisibleContentPosition={
Object {
"minIndexForVisible": 0,
}
}
onContentSizeChange={[Function]}
onLayout={[Function]}
onMomentumScrollBegin={[Function]}
onMomentumScrollEnd={[Function]}
onScroll={[Function]}
onScrollBeginDrag={[Function]}
onScrollEndDrag={[Function]}
renderItem={[Function]}
scrollEventThrottle={50}
stickyHeaderIndices={Array []}
windowSize={1}
>
<View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={0}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={1}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={2}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={3}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={4}
/>
</View>
<View
style={
Object {
"height": 60,
"height": 150,
}
}
/>
</View>
</RCTScrollView>
`;
exports[`handles maintainVisibleContentPosition 2`] = `
<RCTScrollView
data={
Array [
Object {
"key": 20,
},
Object {
"key": 21,
},
Object {
"key": 22,
},
Object {
"key": 23,
},
Object {
"key": 24,
},
Object {
"key": 25,
},
Object {
"key": 26,
},
Object {
"key": 27,
},
Object {
"key": 28,
},
Object {
"key": 29,
},
Object {
"key": 0,
},
Object {
"key": 1,
},
Object {
"key": 2,
},
Object {
"key": 3,
},
Object {
"key": 4,
},
Object {
"key": 5,
},
Object {
"key": 6,
},
Object {
"key": 7,
},
Object {
"key": 8,
},
Object {
"key": 9,
},
Object {
"key": 10,
},
Object {
"key": 11,
},
Object {
"key": 12,
},
Object {
"key": 13,
},
Object {
"key": 14,
},
Object {
"key": 15,
},
Object {
"key": 16,
},
Object {
"key": 17,
},
Object {
"key": 18,
},
Object {
"key": 19,
},
]
}
getItem={[Function]}
getItemCount={[Function]}
getItemLayout={[Function]}
initialNumToRender={1}
maintainVisibleContentPosition={
Object {
"minIndexForVisible": 0,
}
}
onContentSizeChange={[Function]}
onLayout={[Function]}
onMomentumScrollBegin={[Function]}
onMomentumScrollEnd={[Function]}
onScroll={[Function]}
onScrollBeginDrag={[Function]}
onScrollEndDrag={[Function]}
renderItem={[Function]}
scrollEventThrottle={50}
stickyHeaderIndices={Array []}
windowSize={1}
>
<View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={20}
/>
</View>
<View
style={
Object {
"height": 90,
}
}
/>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={0}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={1}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={2}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={3}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={4}
/>
</View>
<View
style={
Object {
"height": 150,
}
}
/>
</View>
</RCTScrollView>
`;
exports[`handles maintainVisibleContentPosition 3`] = `
<RCTScrollView
data={
Array [
Object {
"key": 20,
},
Object {
"key": 21,
},
Object {
"key": 22,
},
Object {
"key": 23,
},
Object {
"key": 24,
},
Object {
"key": 25,
},
Object {
"key": 26,
},
Object {
"key": 27,
},
Object {
"key": 28,
},
Object {
"key": 29,
},
Object {
"key": 0,
},
Object {
"key": 1,
},
Object {
"key": 2,
},
Object {
"key": 3,
},
Object {
"key": 4,
},
Object {
"key": 5,
},
Object {
"key": 6,
},
Object {
"key": 7,
},
Object {
"key": 8,
},
Object {
"key": 9,
},
Object {
"key": 10,
},
Object {
"key": 11,
},
Object {
"key": 12,
},
Object {
"key": 13,
},
Object {
"key": 14,
},
Object {
"key": 15,
},
Object {
"key": 16,
},
Object {
"key": 17,
},
Object {
"key": 18,
},
Object {
"key": 19,
},
]
}
getItem={[Function]}
getItemCount={[Function]}
getItemLayout={[Function]}
initialNumToRender={1}
maintainVisibleContentPosition={
Object {
"minIndexForVisible": 0,
}
}
onContentSizeChange={[Function]}
onLayout={[Function]}
onMomentumScrollBegin={[Function]}
onMomentumScrollEnd={[Function]}
onScroll={[Function]}
onScrollBeginDrag={[Function]}
onScrollEndDrag={[Function]}
renderItem={[Function]}
scrollEventThrottle={50}
stickyHeaderIndices={Array []}
windowSize={1}
>
<View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={20}
/>
</View>
<View
style={
Object {
"height": 80,
}
}
/>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={29}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={0}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={1}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={2}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={3}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={4}
/>
</View>
<View
style={
Object {
"height": 150,
}
}
/>
@@ -4072,21 +4598,12 @@ exports[`renders new items when data is updated with non-zero initialScrollIndex
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={2}
/>
</View>
<View
onFocusCapture={[Function]}
style={null}
>
<MockCellItem
value={3}
/>
</View>
style={
Object {
"height": 20,
}
}
/>
</View>
</RCTScrollView>
`;
@@ -831,6 +831,7 @@ exports[`VirtualizedSectionList renders all the bells and whistles 1`] = `
<RCTRefreshControl />
<View>
<View
collapsable={false}
onLayout={[Function]}
style={
Object {
@@ -1056,6 +1057,7 @@ exports[`VirtualizedSectionList renders empty list with empty component 1`] = `
>
<View>
<View
collapsable={false}
onLayout={[Function]}
>
<header />
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/virtualized-lists",
"version": "0.72.4",
"version": "0.72.5",
"description": "Virtualized lists for React Native.",
"repository": {
"type": "git",
+338 -243
View File
@@ -10,12 +10,12 @@
"@jridgewell/gen-mapping" "^0.1.0"
"@jridgewell/trace-mapping" "^0.3.9"
"@babel/cli@^7.19.0":
version "7.19.3"
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.19.3.tgz#55914ed388e658e0b924b3a95da1296267e278e2"
integrity sha512-643/TybmaCAe101m2tSVHi9UKpETXP9c/Ff4mD2tAwkdP6esKIfaauZFc67vGEM6r9fekbEGid+sZhbEnSe3dg==
"@babel/cli@^7.20.0":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.21.5.tgz#a685a5b50b785f2edfbf6e042c1265c653547d9d"
integrity sha512-TOKytQ9uQW9c4np8F+P7ZfPINy5Kv+pizDIUwSVH8X5zHgYHV4AA8HE5LA450xXeu4jEfmUckTYvv1I4S26M/g==
dependencies:
"@jridgewell/trace-mapping" "^0.3.8"
"@jridgewell/trace-mapping" "^0.3.17"
commander "^4.0.1"
convert-source-map "^1.1.0"
fs-readdir-recursive "^1.1.0"
@@ -38,6 +38,11 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.5.tgz#86f172690b093373a933223b4745deeb6049e733"
integrity sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==
"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.21.5":
version "7.21.7"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.7.tgz#61caffb60776e49a57ba61a88f02bedd8714f6bc"
integrity sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==
"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.20.0":
version "7.20.5"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.5.tgz#45e2114dc6cd4ab167f81daf7820e8fa1250d113"
@@ -59,10 +64,10 @@
json5 "^2.2.1"
semver "^6.3.0"
"@babel/eslint-parser@^7.19.0":
version "7.19.1"
resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz#4f68f6b0825489e00a24b41b6a1ae35414ecd2f4"
integrity sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==
"@babel/eslint-parser@^7.20.0":
version "7.21.8"
resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz#59fb6fc4f3b017ab86987c076226ceef7b2b2ef2"
integrity sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==
dependencies:
"@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1"
eslint-visitor-keys "^2.1.0"
@@ -112,6 +117,17 @@
browserslist "^4.21.3"
semver "^6.3.0"
"@babel/helper-compilation-targets@^7.20.7":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz#631e6cc784c7b660417421349aac304c94115366"
integrity sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==
dependencies:
"@babel/compat-data" "^7.21.5"
"@babel/helper-validator-option" "^7.21.0"
browserslist "^4.21.3"
lru-cache "^5.1.1"
semver "^6.3.0"
"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.2", "@babel/helper-create-class-features-plugin@^7.20.5":
version "7.20.5"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz#327154eedfb12e977baa4ecc72e5806720a85a06"
@@ -241,6 +257,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629"
integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==
"@babel/helper-plugin-utils@^7.21.5":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz#345f2377d05a720a4e5ecfa39cbf4474a4daed56"
integrity sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==
"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9":
version "7.18.9"
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519"
@@ -379,7 +400,7 @@
"@babel/helper-remap-async-to-generator" "^7.18.9"
"@babel/plugin-syntax-async-generators" "^7.8.4"
"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.13.0", "@babel/plugin-proposal-class-properties@^7.18.6":
"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.13.0", "@babel/plugin-proposal-class-properties@^7.18.0", "@babel/plugin-proposal-class-properties@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3"
integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==
@@ -436,7 +457,7 @@
"@babel/helper-plugin-utils" "^7.18.9"
"@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6":
"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1"
integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==
@@ -463,6 +484,17 @@
"@babel/plugin-syntax-object-rest-spread" "^7.8.3"
"@babel/plugin-transform-parameters" "^7.20.1"
"@babel/plugin-proposal-object-rest-spread@^7.20.0":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a"
integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==
dependencies:
"@babel/compat-data" "^7.20.5"
"@babel/helper-compilation-targets" "^7.20.7"
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/plugin-syntax-object-rest-spread" "^7.8.3"
"@babel/plugin-transform-parameters" "^7.20.7"
"@babel/plugin-proposal-optional-catch-binding@^7.0.0", "@babel/plugin-proposal-optional-catch-binding@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb"
@@ -471,7 +503,7 @@
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
"@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.18.9":
"@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.18.9":
version "7.18.9"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993"
integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==
@@ -480,6 +512,15 @@
"@babel/helper-skip-transparent-expression-wrappers" "^7.18.9"
"@babel/plugin-syntax-optional-chaining" "^7.8.3"
"@babel/plugin-proposal-optional-chaining@^7.20.0":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea"
integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==
dependencies:
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
"@babel/plugin-syntax-optional-chaining" "^7.8.3"
"@babel/plugin-proposal-private-methods@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea"
@@ -534,7 +575,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-syntax-dynamic-import@^7.0.0", "@babel/plugin-syntax-dynamic-import@^7.8.3":
"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3"
integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==
@@ -660,7 +701,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/plugin-transform-async-to-generator@^7.0.0", "@babel/plugin-transform-async-to-generator@^7.18.6":
"@babel/plugin-transform-async-to-generator@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615"
integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==
@@ -669,6 +710,15 @@
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/helper-remap-async-to-generator" "^7.18.6"
"@babel/plugin-transform-async-to-generator@^7.20.0":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz#dfee18623c8cb31deb796aa3ca84dda9cea94354"
integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==
dependencies:
"@babel/helper-module-imports" "^7.18.6"
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/helper-remap-async-to-generator" "^7.18.9"
"@babel/plugin-transform-block-scoped-functions@^7.0.0", "@babel/plugin-transform-block-scoped-functions@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8"
@@ -712,6 +762,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/plugin-transform-destructuring@^7.20.0":
version "7.21.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz#73b46d0fd11cd6ef57dea8a381b1215f4959d401"
integrity sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==
dependencies:
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8"
@@ -743,6 +800,14 @@
"@babel/helper-plugin-utils" "^7.19.0"
"@babel/plugin-syntax-flow" "^7.18.6"
"@babel/plugin-transform-flow-strip-types@^7.20.0", "@babel/plugin-transform-flow-strip-types@^7.21.0":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz#6aeca0adcb81dc627c8986e770bfaa4d9812aff5"
integrity sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==
dependencies:
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/plugin-syntax-flow" "^7.18.6"
"@babel/plugin-transform-for-of@^7.0.0", "@babel/plugin-transform-for-of@^7.18.8":
version "7.18.8"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1"
@@ -838,6 +903,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/plugin-transform-parameters@^7.20.7":
version "7.21.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz#18fc4e797cf6d6d972cb8c411dbe8a809fa157db"
integrity sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==
dependencies:
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/plugin-transform-property-literals@^7.0.0", "@babel/plugin-transform-property-literals@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3"
@@ -877,7 +949,7 @@
"@babel/plugin-syntax-jsx" "^7.18.6"
"@babel/types" "^7.19.0"
"@babel/plugin-transform-regenerator@^7.0.0", "@babel/plugin-transform-regenerator@^7.18.6":
"@babel/plugin-transform-regenerator@^7.18.6":
version "7.20.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz#57cda588c7ffb7f4f8483cc83bdcea02a907f04d"
integrity sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==
@@ -885,6 +957,14 @@
"@babel/helper-plugin-utils" "^7.20.2"
regenerator-transform "^0.15.1"
"@babel/plugin-transform-regenerator@^7.20.0":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz#576c62f9923f94bcb1c855adc53561fd7913724e"
integrity sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w==
dependencies:
"@babel/helper-plugin-utils" "^7.21.5"
regenerator-transform "^0.15.1"
"@babel/plugin-transform-reserved-words@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a"
@@ -973,7 +1053,7 @@
"@babel/helper-create-regexp-features-plugin" "^7.18.6"
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/preset-env@^7.14.0", "@babel/preset-env@^7.20.0":
"@babel/preset-env@^7.20.0":
version "7.20.2"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.20.2.tgz#9b1642aa47bb9f43a86f9630011780dab7f86506"
integrity sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==
@@ -1054,7 +1134,7 @@
core-js-compat "^3.25.1"
semver "^6.3.0"
"@babel/preset-flow@^7.13.13", "@babel/preset-flow@^7.18.0":
"@babel/preset-flow@^7.13.13":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.18.6.tgz#83f7602ba566e72a9918beefafef8ef16d2810cb"
integrity sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ==
@@ -1063,6 +1143,15 @@
"@babel/helper-validator-option" "^7.18.6"
"@babel/plugin-transform-flow-strip-types" "^7.18.6"
"@babel/preset-flow@^7.20.0":
version "7.21.4"
resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.21.4.tgz#a5de2a1cafa61f0e0b3af9b30ff0295d38d3608f"
integrity sha512-F24cSq4DIBmhq4OzK3dE63NHagb27OPE3eWR+HLekt4Z3Y5MzIIUGF3LlLgV0gN8vzbDViSY7HnrReNVCJXTeA==
dependencies:
"@babel/helper-plugin-utils" "^7.20.2"
"@babel/helper-validator-option" "^7.21.0"
"@babel/plugin-transform-flow-strip-types" "^7.21.0"
"@babel/preset-modules@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9"
@@ -2026,7 +2115,7 @@
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.8", "@jridgewell/trace-mapping@^0.3.9":
"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.9":
version "0.3.15"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774"
integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==
@@ -2248,44 +2337,44 @@
optionalDependencies:
npmlog "2 || ^3.1.0 || ^4.0.0"
"@react-native-community/cli-clean@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-11.2.3.tgz#5349719639e04ecd11f847ed83fe3a4af800c250"
integrity sha512-+fg8KtVOSzRmtgkmFUKPJwFHOa4UzrrExPc8uURH7rFF7Y4epU9xdbeHGc37L46NmJ/vc7PC59DoOU730d0aYg==
"@react-native-community/cli-clean@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-11.3.2.tgz#45dc0aa379deeb13834b661f8eeb2e63ed34316f"
integrity sha512-OIKeP8fYtaa9qw4bpf1m3WJDWx4GvcxTYkyycH5SDu+pZjYWNix7XtKhwoL3Ol2NJLWxdY4LnmQG1yy8OGeIRw==
dependencies:
"@react-native-community/cli-tools" "11.2.3"
"@react-native-community/cli-tools" "11.3.2"
chalk "^4.1.2"
execa "^5.0.0"
prompts "^2.4.0"
"@react-native-community/cli-config@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-11.2.3.tgz#86a75189ad22af4ec6637f10d41fee540ca8cbc1"
integrity sha512-rh/ggarwxpZzlhImSV4AKj3qp2gS518c7dyvQxNOpi6zlwPIXOsOuYwgUa0UBbNmSqIMwdvJMtFoAaT3LODELQ==
"@react-native-community/cli-config@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-11.3.2.tgz#1bf268589f7261920dd65a78d7a0a1099792a7f9"
integrity sha512-hMAIR3QTjzDUmOSsbroXeNkZAcf8lpOGo1fj8CwJNfjuVho1RZZSlHKp8G7FU2sgqZmb8jWN+9tFvCRACXVYoQ==
dependencies:
"@react-native-community/cli-tools" "11.2.3"
"@react-native-community/cli-tools" "11.3.2"
chalk "^4.1.2"
cosmiconfig "^5.1.0"
deepmerge "^4.3.0"
glob "^7.1.3"
joi "^17.2.1"
"@react-native-community/cli-debugger-ui@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-11.2.3.tgz#33181838153ce80baad989ebe18104dc85819528"
integrity sha512-Vb+WNt1EEr9AGT4Nl7LYHrnEQYYc5wQs5QsYXD2VpPy+7J70jjmpPL+sEEWWEEgBa6ER5tXl5DrDcj/3VMLiQA==
"@react-native-community/cli-debugger-ui@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-11.3.2.tgz#35f29daf8354e8e516cb05ca471fb705780efdd7"
integrity sha512-pAKBcjrNl0iJoi42Ekqn3UH/QZ48pxfAIhsKkc3WmBqYetdByobhkYWfchHq3j9bilgiaBquPQaKzkg69kQw3w==
dependencies:
serve-static "^1.13.1"
"@react-native-community/cli-doctor@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-11.2.3.tgz#903f726058227680c09e2e34cdeb9f8e3f857e21"
integrity sha512-Y8Fqc36E/yhZ9XwRxg4PdQkT+awM7O7vec767nYDmIVyuUaZCRwBqex2jdjzZgLHMz9TEHcG3Th+LLHERkpN8Q==
"@react-native-community/cli-doctor@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-11.3.2.tgz#d8eb867b80da66ce7b11e0e6e4e07ab152ffbf7b"
integrity sha512-tvmAQzz+qOJwtBCVEdhHweMeGaoHauGn3ef4tsHyqlDc0fF1K5No9DGXSESlLHpsopg066sIHWGq0PmAIeChiA==
dependencies:
"@react-native-community/cli-config" "11.2.3"
"@react-native-community/cli-platform-android" "11.2.3"
"@react-native-community/cli-platform-ios" "11.2.3"
"@react-native-community/cli-tools" "11.2.3"
"@react-native-community/cli-config" "11.3.2"
"@react-native-community/cli-platform-android" "11.3.2"
"@react-native-community/cli-platform-ios" "11.3.2"
"@react-native-community/cli-tools" "11.3.2"
chalk "^4.1.2"
command-exists "^1.2.8"
envinfo "^7.7.2"
@@ -2301,64 +2390,64 @@
wcwidth "^1.0.1"
yaml "^2.2.1"
"@react-native-community/cli-hermes@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-11.2.3.tgz#a215a8b56d8407304eeb47c36fca6bce98a67455"
integrity sha512-377V6Lqj2RDYoEtwDTfTA9ldeEAE3+jGBOP+q0E35dTWkeCDR1Bwu7D9Z38WLfWt89XJr64VUUSVdgHYBJ1FNw==
"@react-native-community/cli-hermes@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-11.3.2.tgz#842b21a1cd3960295eed3591ab81e6f9e68aa606"
integrity sha512-IfzdYTjxu+BFEvweY9TXpLkOmWq0sxK8PTN+u0BduiT9cJRvcO0CxjOpLHAabVrSJc6o+7aLfEvogBmdN53Xfg==
dependencies:
"@react-native-community/cli-platform-android" "11.2.3"
"@react-native-community/cli-tools" "11.2.3"
"@react-native-community/cli-platform-android" "11.3.2"
"@react-native-community/cli-tools" "11.3.2"
chalk "^4.1.2"
hermes-profile-transformer "^0.0.6"
ip "^1.1.5"
"@react-native-community/cli-platform-android@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-11.2.3.tgz#57440d727a7f2bfef8e60c5fd791a4362f99df88"
integrity sha512-MJHKY3ceQOQHZlSPO1CpEDUsyrwLIQrZ4DwFZiVR0i/+gBTmWXx547xD2V5o50wFj1YAeciJTuxKqa2JjLVuPg==
"@react-native-community/cli-platform-android@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-11.3.2.tgz#d9528306c3751f7d6d1fd3d5a56187708dd65829"
integrity sha512-NKxyBP0/gwL4/tNWrkevFSjeb7Dw2SByNfE9wFXBaAvZHxbxxJUjZOTOW3ueOXEpgOMU7IYYOiSOz2M10IRQ2A==
dependencies:
"@react-native-community/cli-tools" "11.2.3"
"@react-native-community/cli-tools" "11.3.2"
chalk "^4.1.2"
execa "^5.0.0"
glob "^7.1.3"
logkitty "^0.7.1"
"@react-native-community/cli-platform-ios@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-11.2.3.tgz#b2b8b4d080a7628317fbe0afe5cc62ee3033a2dd"
integrity sha512-AC2hfqwFYuG2ZHXQRHpPDFFZ8IDPcCjpxVJCFi0R9/QNayEH8xsfmVzs1Hd4jKV0JjgCf+jxI/nCtxqreEdl0g==
"@react-native-community/cli-platform-ios@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-11.3.2.tgz#cfecce27641950603d736e1f41fcae088e3ada1f"
integrity sha512-XPrfsI7dNY3f9crsKDDRIss+GHYX/snuYfMrjg4ZBHpYB5JdLepO8FJ5bFz+/s9KXDm045ijo8QFcIf3XJR0YQ==
dependencies:
"@react-native-community/cli-tools" "11.2.3"
"@react-native-community/cli-tools" "11.3.2"
chalk "^4.1.2"
execa "^5.0.0"
fast-xml-parser "^4.0.12"
glob "^7.1.3"
ora "^5.4.1"
"@react-native-community/cli-plugin-metro@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-11.2.3.tgz#b079895b7d118d99946681be4495496a84bde2c7"
integrity sha512-mYuQT40LgzSHNsGuQqHdAII2z8ZQU58rQsa9Dv0aWuLwTFwEGsVXjHIW5+L16RIIvNWIXIZBI029TYJEWNPeVA==
"@react-native-community/cli-plugin-metro@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-11.3.2.tgz#dbdf6d04b3c608a11dea833a9f882420352dda44"
integrity sha512-r1rZYCFfxZWIiUlukjMcDlxfCtm+QNYu+vFyVfE9yvN9gaNPBAi9029eVzkRkFuJ8Rxwr67HnYEAdGYLWQ1uIw==
dependencies:
"@react-native-community/cli-server-api" "11.2.3"
"@react-native-community/cli-tools" "11.2.3"
"@react-native-community/cli-server-api" "11.3.2"
"@react-native-community/cli-tools" "11.3.2"
chalk "^4.1.2"
execa "^5.0.0"
metro "0.76.4"
metro-config "0.76.4"
metro-core "0.76.4"
metro-react-native-babel-transformer "0.76.4"
metro-resolver "0.76.4"
metro-runtime "0.76.4"
metro "0.76.5"
metro-config "0.76.5"
metro-core "0.76.5"
metro-react-native-babel-transformer "0.76.5"
metro-resolver "0.76.5"
metro-runtime "0.76.5"
readline "^1.3.0"
"@react-native-community/cli-server-api@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-11.2.3.tgz#d14ae991ccff163cc3fad5cee1deda4bb28efa26"
integrity sha512-PtvzFlGlV+i9ZPMzFzlThHFHRc2ZiU4RVGoVlhnmJZN872y1haU6xv1/5alCjSf6K+MbXPE9YqYma4+n47eOxA==
"@react-native-community/cli-server-api@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-11.3.2.tgz#79f06606aa1cf7f84dc5c4c53f9a6de0d98142d4"
integrity sha512-6rMb37HYWOdmiMGCxsttHDLIP7KmcJjWvzTJzb2tm9P5FoMvSSmSOn981MuP835Lk1U+IdjVcwtsA247Im4mkg==
dependencies:
"@react-native-community/cli-debugger-ui" "11.2.3"
"@react-native-community/cli-tools" "11.2.3"
"@react-native-community/cli-debugger-ui" "11.3.2"
"@react-native-community/cli-tools" "11.3.2"
compression "^1.7.1"
connect "^3.6.5"
errorhandler "^1.5.1"
@@ -2367,10 +2456,10 @@
serve-static "^1.13.1"
ws "^7.5.1"
"@react-native-community/cli-tools@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-11.2.3.tgz#2982140e1da4a4b9f519884299153502c5b6aa59"
integrity sha512-sfHflRQRNOShkCUbNOBWvIgBxuO20UEBMHwDVb4Im6bidDHdd4Tby2hlveJ8wCW2r+aDyHKsIN0CeX4vMYhFzQ==
"@react-native-community/cli-tools@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-11.3.2.tgz#29c01e0978199e3d65a2ed234a629a9cf05db8ca"
integrity sha512-rAnFPzRITeEhBLwC73ucvWsYjsGyotSOI4c+k8t9wUqcIk1Q+RFnuWozGc13msOPdESvBHt2MPJBwXrtKgKn1g==
dependencies:
appdirsjs "^1.2.4"
chalk "^4.1.2"
@@ -2382,27 +2471,27 @@
semver "^6.3.0"
shell-quote "^1.7.3"
"@react-native-community/cli-types@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-11.2.3.tgz#234967c9cfdb15e638ca2d903147f0b0c9b7ca55"
integrity sha512-beh/S3fwjNaoLfknYefnMqcjNW6qtKJ+tUDewfMDbkwA57+o2bvBRExM/4jik7qPRBFhtqQ400Z8gVx4zOMgFw==
"@react-native-community/cli-types@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-11.3.2.tgz#09531e83ddda582c7321752d1d80674578bc8ea7"
integrity sha512-jba1Z1YgC4JIHPADSqpl4ATsrJaOja1zlQCbH/yE8McHRjVBzeYGeHIvG5jw7iU5cw6FFifH5vvr23JPGk8oyw==
dependencies:
joi "^17.2.1"
"@react-native-community/cli@11.2.3":
version "11.2.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-11.2.3.tgz#9380590c8c784b37af8070b34948a44330f529e0"
integrity sha512-IAjlRRsWJM8CvUQ/3I0Y/oCJuBGoqXNq0jcfQfSNfm2OWP6u+3dsmvFg/ow7t4saYJ9BIfHIoDsqmkgwU/RCCQ==
"@react-native-community/cli@11.3.2":
version "11.3.2"
resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-11.3.2.tgz#a14c341c2421a929a322b11d02a60f7ac8ff5ee9"
integrity sha512-riyMvro6HH2NLUhcnjUrOFwi2IHb6/GOC1WKf7GvGH1L4KnIo/jP4Sk9QV+pROg1Gd9btrCTnyY7WbWuPWJJ3w==
dependencies:
"@react-native-community/cli-clean" "11.2.3"
"@react-native-community/cli-config" "11.2.3"
"@react-native-community/cli-debugger-ui" "11.2.3"
"@react-native-community/cli-doctor" "11.2.3"
"@react-native-community/cli-hermes" "11.2.3"
"@react-native-community/cli-plugin-metro" "11.2.3"
"@react-native-community/cli-server-api" "11.2.3"
"@react-native-community/cli-tools" "11.2.3"
"@react-native-community/cli-types" "11.2.3"
"@react-native-community/cli-clean" "11.3.2"
"@react-native-community/cli-config" "11.3.2"
"@react-native-community/cli-debugger-ui" "11.3.2"
"@react-native-community/cli-doctor" "11.3.2"
"@react-native-community/cli-hermes" "11.3.2"
"@react-native-community/cli-plugin-metro" "11.3.2"
"@react-native-community/cli-server-api" "11.3.2"
"@react-native-community/cli-tools" "11.3.2"
"@react-native-community/cli-types" "11.3.2"
chalk "^4.1.2"
commander "^9.4.1"
execa "^5.0.0"
@@ -3359,7 +3448,7 @@ camelcase@^5.0.0, camelcase@^5.3.1:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
camelcase@^6.0.0, camelcase@^6.2.0:
camelcase@^6.2.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
@@ -4601,11 +4690,16 @@ flow-enums-runtime@^0.0.5:
resolved "https://registry.yarnpkg.com/flow-enums-runtime/-/flow-enums-runtime-0.0.5.tgz#95884bfcc82edaf27eef7e1dd09732331cfbafbc"
integrity sha512-PSZF9ZuaZD03sT9YaIs0FrGJ7lSUw7rHZIex+73UYVXg46eL/wxN5PaVcPJFudE2cJu5f0fezitV5aBkLHPUOQ==
flow-parser@0.*, flow-parser@^0.185.0:
flow-parser@0.*:
version "0.185.0"
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.185.0.tgz#56bde60805bad19b2934ebfc50c9485e5c5424f9"
integrity sha512-VWpXjEbQbIGQvB6CyWwx56wMioGZ6w2s8qJlFiuE3S7D8O+xE5t988i1u2TGFO5TLSzQPUhfIOzPpLYA93H9Jg==
flow-parser@^0.206.0:
version "0.206.0"
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.206.0.tgz#f4f794f8026535278393308e01ea72f31000bfef"
integrity sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w==
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
@@ -5557,11 +5651,6 @@ jest-get-type@^24.9.0:
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e"
integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==
jest-get-type@^26.3.0:
version "26.3.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0"
integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==
jest-get-type@^29.2.0:
version "29.2.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408"
@@ -5798,18 +5887,6 @@ jest-validate@^24.9.0:
leven "^3.1.0"
pretty-format "^24.9.0"
jest-validate@^26.5.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec"
integrity sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==
dependencies:
"@jest/types" "^26.6.2"
camelcase "^6.0.0"
chalk "^4.0.0"
jest-get-type "^26.3.0"
leven "^3.1.0"
pretty-format "^26.6.2"
jest-validate@^29.2.1:
version "29.2.1"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.2.1.tgz#db814ce12c4c7e4746044922762e56eb177d066c"
@@ -5916,6 +5993,11 @@ jsc-android@^250231.0.0:
resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-250231.0.0.tgz#91720f8df382a108872fa4b3f558f33ba5e95262"
integrity sha512-rS46PvsjYmdmuz1OAWXY/1kCYG7pnf1TBqeTiOJr1iDz7s5DLxxC9n/ZMknLDxzYzNVfI7R95MH10emSSG1Wuw==
jsc-safe-url@^0.2.2:
version "0.2.4"
resolved "https://registry.yarnpkg.com/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz#141c14fbb43791e88d5dc64e85a374575a83477a"
integrity sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==
jscodeshift@^0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.14.0.tgz#7542e6715d6d2e8bde0b4e883f0ccea358b46881"
@@ -6255,6 +6337,13 @@ lowercase-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
lru-cache@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
dependencies:
yallist "^3.0.2"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@@ -6306,66 +6395,66 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
metro-babel-register@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.76.4.tgz#2c6f04fa10d82ccce01c90b6211f77ef7bcb2626"
integrity sha512-k2xmUnJQn8VsLtyWS59yJ5YIIje8YJgO544O2XQjNsCWhkr4YW9N0iItchtnvmJFthsAS4z6eglLT27fM4HLsQ==
metro-babel-register@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.76.5.tgz#2b3826b2f5b76eda0e2def966244653aec270506"
integrity sha512-5S7G8Gn+MS1rBjH54BJXCIzKUjAlr8KRUskw4BFFG6cAtX+zTtbSdWQydKNw7fC0VuB/tRJkC2OTvYmnPNPN3g==
dependencies:
"@babel/core" "^7.20.0"
"@babel/plugin-transform-flow-strip-types" "^7.0.0"
"@babel/plugin-transform-flow-strip-types" "^7.20.0"
"@babel/plugin-transform-modules-commonjs" "^7.0.0"
"@babel/preset-typescript" "^7.18.0"
"@babel/register" "^7.0.0"
babel-plugin-replace-ts-export-assignment "^0.0.2"
escape-string-regexp "^1.0.5"
metro-babel-transformer@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.76.4.tgz#d5ebcae4dd1ba1b15eb7de288d0347f5f52d1432"
integrity sha512-VTvCj6wnYfg5TeFrASegdGqPrdoPsfPbS0g0yd3VzZlDJpMN+qhYH5Qn0ERFK5I0LLedjHlOrSZzOhlElFEbPw==
metro-babel-transformer@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.76.5.tgz#1daea5b236c52579c9e9a04b94ae9f9677a81f3d"
integrity sha512-KmsMXY6VHjPLRQLwTITjLo//7ih8Ts39HPF2zODkaYav/ZLNq0QP7eGuW54dvk/sZiL9le1kaBwTN4BWQI1VZQ==
dependencies:
"@babel/core" "^7.20.0"
hermes-parser "0.8.0"
metro-source-map "0.76.4"
metro-source-map "0.76.5"
nullthrows "^1.1.1"
metro-cache-key@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.76.4.tgz#684d7ffd2b2936be824475296eaaf9a1374b9835"
integrity sha512-bh7GFqPg4+IKolI0ybalotqyMU/nbHxyXrKad7bwhUI0z6RSNv0ImXGtDWzzMQ6tCPV2MTCDzzSPLEXLeUVH8A==
metro-cache-key@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.76.5.tgz#9b5b7d7e24fa75c95b9e672c0f0a7a19b2a16508"
integrity sha512-QERX6ejYMt4BPr0ZMf7adnrOivmFSUbCim9FlU6cAeWUib+pV5P/Ph3KicWnOzJpbQz93+tHHG7vcsP6OrvLMw==
metro-cache@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.76.4.tgz#cfd35f817c06148c5f53ea25b737469abce14447"
integrity sha512-pWQTKbA92XUhg9QVCwDsKwBxyZrjYPs8fYCnqB1phF+r26Vj4VYVKLAZam4lxFXC+awiEpYzpgmQkfwqODZE0g==
metro-cache@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.76.5.tgz#479c4e036ab89c68f12551a354ccaaf759eb9a40"
integrity sha512-8XalhoMNWDK6bi41oqxIpecTYRt4WsmtoHdqshgJIYshJ6qov0NuDw0pOfnS8rgMNHxPpuWyXc7NyKERqVRzaw==
dependencies:
metro-core "0.76.4"
metro-core "0.76.5"
rimraf "^3.0.2"
metro-config@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.76.4.tgz#28753ab0671705914c75a945e85f671922ea128f"
integrity sha512-o0rK5HnQZoCI6xfVgtjkMyBVcj6UZ4c6lbr8MwRzjIH6rKyoetxdM6OCnnBcZgCmid10apYdveaIQBJ7KYCNlg==
metro-config@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.76.5.tgz#74624b68cff4e72576129d4e59ff8c22a7171e45"
integrity sha512-SCMVIDOtm8s3H62E9z2IcY4Q9GVMqDurbiJS3PHrWgTZjwZFaL59lrW4W6DvzvFZHa9bbxKric5TFtwvVuyOCg==
dependencies:
cosmiconfig "^5.0.5"
jest-validate "^26.5.2"
metro "0.76.4"
metro-cache "0.76.4"
metro-core "0.76.4"
metro-runtime "0.76.4"
jest-validate "^29.2.1"
metro "0.76.5"
metro-cache "0.76.5"
metro-core "0.76.5"
metro-runtime "0.76.5"
metro-core@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.76.4.tgz#51aa3065ec324112827d44f881e39a38bdd8813a"
integrity sha512-zrWl2MLvW8Nxa4sX5wnPm1cPvAu5J3DmnUMHK5PHELgJGtb5XNV7UibxmI/6zM423OQH1KPY7Hh5l3qkn4cDRQ==
metro-core@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.76.5.tgz#0196dbb32bfb3c3edd288e908daf360764c89105"
integrity sha512-yJvIe8a3sAG92U7+E7Bw6m4lae9RB180fp9iQZFBqY437Ilv4nE6PR8EWB6d8c4yt9fXIL1Hc+KyQv7OPFx/rQ==
dependencies:
lodash.throttle "^4.1.1"
metro-resolver "0.76.4"
metro-resolver "0.76.5"
metro-file-map@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.76.4.tgz#c355018f176900a21cf2cf95a46b0c9a3012eaec"
integrity sha512-k/FPwqdZVYnyaB3Ar+dlA37RVs6TNx8hBkGj28gQE/8E2bfDDRSFlCPe69M92fcSUZDVPZqC2vS7lDmUa3xxQQ==
metro-file-map@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.76.5.tgz#71f40660adfa1a806907f7961ef2a57884501d6c"
integrity sha512-9VS7zsec7BpTb+0v1DObOXso6XU/7oVBObQWp0EWBQpFcU1iF1lit2nnLQh2AyGCnSr8JVnuUe8gXhNH6xtPMg==
dependencies:
anymatch "^3.0.3"
debug "^2.2.0"
@@ -6382,10 +6471,10 @@ metro-file-map@0.76.4:
optionalDependencies:
fsevents "^2.3.2"
metro-inspector-proxy@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.76.4.tgz#0d609cdbb8a31ac43665fb567079adee47e7f385"
integrity sha512-gsnUagRBoNgaWjcwD9eeweJwAw6pvMxKywZNM5HBvU2FfXnJT1BrHZznaL5ABCPhJKHcO9MvnJT2fo6x09owfg==
metro-inspector-proxy@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.76.5.tgz#aac222b0680c7c031e24b6246d995ca3e87868f2"
integrity sha512-leqwei1qNMKOEbhqlQ37K+7OIp1JRgvS5qERO+J0ZTg7ZeJTaBHSFU7FnCeRHB9Tu7/FSfypY2PxjydZDwvUEQ==
dependencies:
connect "^3.6.5"
debug "^2.2.0"
@@ -6393,51 +6482,51 @@ metro-inspector-proxy@0.76.4:
ws "^7.5.1"
yargs "^17.6.2"
metro-memory-fs@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.76.4.tgz#aacad3a6140e6f04bd6db992ea2640b3ee7fbaf2"
integrity sha512-7EWmYqQErJiyqiqbz7eGXWGzChuHMIc6hZkn21gfUh65YRA7PuQrSfn4CbXixG1ZZkUGjPibBH2e0nHSZDGRSQ==
metro-memory-fs@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-memory-fs/-/metro-memory-fs-0.76.5.tgz#6d08342bfec0d99f53ecbae5bc5c04d4262b696c"
integrity sha512-kw7iTabGEIdTLZfjoadHvYT8ZYj9Dvy1oJvulFPST83My9qjGqJToOrfXVO/duvpwHuT7dIffsefzcyNOianJQ==
metro-minify-terser@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.76.4.tgz#e02bc231a39f23c9dad513abf42ca50b2c111887"
integrity sha512-u4MqTTE30UkUV3zqj3wX1QWqXc6SS2uLRk1DQCelmB6fLzqVQR0xe00hlnzkxc/V4w8x19Bs00lPpAEOzGXNvQ==
metro-minify-terser@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.76.5.tgz#1bde3e0bcad27ec1764f78075637782ace127dba"
integrity sha512-zizTXqlHcG7PArB5hfz1Djz/oCaOaTSXTZDNp8Y9K2FmmfLU3dU2eoDbNNiCnm5QdDtFIndLMXdqqe6omTfp4g==
dependencies:
terser "^5.15.0"
metro-minify-uglify@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.76.4.tgz#62604b972caf114baf1a968155fd27e876017432"
integrity sha512-LNGEYzk12xLld63NrMEnJdmdwk6nife9cylahm0V3SOa8wN16j9004aGywrBajOJEAqoF4nbrVgzfAs2tB3nZA==
metro-minify-uglify@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.76.5.tgz#afbb5e3bbc9ca05a9a63d1c5fd74dfc9c1b4c4f8"
integrity sha512-JZNO5eK8r625/cheWSl+y7n0RlHLt03iSMgXPAxirH8BiFqPzs7h+c57r4AvSs793VXcF7L3sI1sAOj+nRqTeg==
dependencies:
uglify-es "^3.1.9"
metro-react-native-babel-preset@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.76.4.tgz#f9422a62348c3fe9c2f733fe005e75b97345f4b1"
integrity sha512-BKyfPz7mn3ncgRjqi8Z9nYLbzuuiBWns2AAEIGctQdz9OMMAisPlZmWscv09UjhPXkQc/XtToFETVN7fmHMfug==
metro-react-native-babel-preset@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.76.5.tgz#5379e163e014dce14066d277628ae018fda79593"
integrity sha512-IlVKeTon5fef77rQ6WreSmrabmbc3dEsLwr/sL80fYjobjsD8FRCnOlbaJdgUf2SMJmSIoawgjh5Yeebv+gJzg==
dependencies:
"@babel/core" "^7.20.0"
"@babel/plugin-proposal-async-generator-functions" "^7.0.0"
"@babel/plugin-proposal-class-properties" "^7.0.0"
"@babel/plugin-proposal-class-properties" "^7.18.0"
"@babel/plugin-proposal-export-default-from" "^7.0.0"
"@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0"
"@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.0"
"@babel/plugin-proposal-numeric-separator" "^7.0.0"
"@babel/plugin-proposal-object-rest-spread" "^7.0.0"
"@babel/plugin-proposal-object-rest-spread" "^7.20.0"
"@babel/plugin-proposal-optional-catch-binding" "^7.0.0"
"@babel/plugin-proposal-optional-chaining" "^7.0.0"
"@babel/plugin-syntax-dynamic-import" "^7.0.0"
"@babel/plugin-proposal-optional-chaining" "^7.20.0"
"@babel/plugin-syntax-dynamic-import" "^7.8.0"
"@babel/plugin-syntax-export-default-from" "^7.0.0"
"@babel/plugin-syntax-flow" "^7.18.0"
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0"
"@babel/plugin-syntax-optional-chaining" "^7.0.0"
"@babel/plugin-transform-arrow-functions" "^7.0.0"
"@babel/plugin-transform-async-to-generator" "^7.0.0"
"@babel/plugin-transform-async-to-generator" "^7.20.0"
"@babel/plugin-transform-block-scoping" "^7.0.0"
"@babel/plugin-transform-classes" "^7.0.0"
"@babel/plugin-transform-computed-properties" "^7.0.0"
"@babel/plugin-transform-destructuring" "^7.0.0"
"@babel/plugin-transform-flow-strip-types" "^7.0.0"
"@babel/plugin-transform-destructuring" "^7.20.0"
"@babel/plugin-transform-flow-strip-types" "^7.20.0"
"@babel/plugin-transform-function-name" "^7.0.0"
"@babel/plugin-transform-literals" "^7.0.0"
"@babel/plugin-transform-modules-commonjs" "^7.0.0"
@@ -6457,62 +6546,62 @@ metro-react-native-babel-preset@0.76.4:
babel-plugin-transform-flow-enums "^0.0.2"
react-refresh "^0.4.0"
metro-react-native-babel-transformer@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.76.4.tgz#16dbdd4c898ee127a9e14a0ef4d3a88659b76f1c"
integrity sha512-gxiTuXKls8N1JUGeblbofUL/5h3GOOcdpUB/yEeuUx6WIp1ovTlmsCb69W3I4zH5HFQkczTynnX4z358Foefpw==
metro-react-native-babel-transformer@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.76.5.tgz#08b7d4a0240ebdafc1f2ff0691a70a7f507a0de0"
integrity sha512-7m2u7jQ1I2mwGm48Vrki5cNNSv4d2HegHMGmE5G2AAa6Pr2O3ajaX2yNoAKF8TCLO38/8pa9fZd0VWAlO/YMcA==
dependencies:
"@babel/core" "^7.20.0"
babel-preset-fbjs "^3.4.0"
hermes-parser "0.8.0"
metro-babel-transformer "0.76.4"
metro-react-native-babel-preset "0.76.4"
metro-source-map "0.76.4"
metro-babel-transformer "0.76.5"
metro-react-native-babel-preset "0.76.5"
metro-source-map "0.76.5"
nullthrows "^1.1.1"
metro-resolver@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.76.4.tgz#34bf2c9f8c9bacbc71e7ecbfb6b64e998c5910ff"
integrity sha512-SXVNS+j055FLiAWx5Lems4Yw/dMxm6uo8j2ew76C+Vib++aSA/hcEoYHy1GB63jG6FmymPH3yrnyX0F6mcRnsQ==
metro-resolver@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.76.5.tgz#9d5521d73d1f5e651e36a3d80aa0e6c3a4a74f6f"
integrity sha512-QNsbDdf0xL1HefP6fhh1g3umqiX1qWEuCiBaTFroYRqM7u7RATt8mCu4n/FwSYhATuUUujHTIb2EduuQPbSGRQ==
metro-runtime@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.76.4.tgz#10cf5d9b6be7a52d4990a40f0183e994b9338201"
integrity sha512-ngNjwPTUrU3thjPZq+0zw/kwFHCtSx4WTIbxw3DNAyxzrgimgoYqtJb9KVFbE/d4Juan+JHymSDtovJstOMjmw==
metro-runtime@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.76.5.tgz#546d3baf498b2736565c0781810c80bd9d81212e"
integrity sha512-1JAf9/v/NDHLhoTfiJ0n25G6dRkX7mjTkaMJ6UUXIyfIuSucoK5yAuOBx8OveNIekoLRjmyvSmyN5ojEeRmpvQ==
dependencies:
"@babel/runtime" "^7.0.0"
react-refresh "^0.4.0"
metro-source-map@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.76.4.tgz#ab24b3969db4cc8d63015ed95402e1afde29a0a2"
integrity sha512-+nWoqIhzEwi6adSYHpmJN9KUfrW1Gpm17ZpE0JpkWHYvzKs9PDGvQkrd0lYmFiW5Cnfxm8D3rdVqAaH9rYincw==
metro-source-map@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.76.5.tgz#786153fcc93609c7d41c22cae16082b69cd60429"
integrity sha512-1EhYPcoftONlvnOzgos7daE8hsJKOgSN3nD3Xf/yaY1F0aLeGeuWfpiNLLeFDNyUhfObHSuNxNhDQF/x1GFEbw==
dependencies:
"@babel/traverse" "^7.20.0"
"@babel/types" "^7.20.0"
invariant "^2.2.4"
metro-symbolicate "0.76.4"
metro-symbolicate "0.76.5"
nullthrows "^1.1.1"
ob1 "0.76.4"
ob1 "0.76.5"
source-map "^0.5.6"
vlq "^1.0.0"
metro-symbolicate@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.76.4.tgz#af0f68ed4b0196091d5c0d7c72b9b7dcdf2e8d69"
integrity sha512-k2WkvGNx35PkLwucf20E1uvC2CB2AI+svoBY5T2c864gf77bh94t8cM9/Bi3up36QG5001pHtxTXS4frb59Mew==
metro-symbolicate@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.76.5.tgz#f2fbb75ca9436ea053bde702fa2a20146ff10be1"
integrity sha512-7iftzh6G6HO4UDBmjsi2Yu4d6IkApv6Kg+jmBvkTjCXr8HwnKKum89gMg/FRMix+Rhhut0dnMpz6mAbtKTU9JQ==
dependencies:
invariant "^2.2.4"
metro-source-map "0.76.4"
metro-source-map "0.76.5"
nullthrows "^1.1.1"
source-map "^0.5.6"
through2 "^2.0.1"
vlq "^1.0.0"
metro-transform-plugins@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.76.4.tgz#31d74ef1c6431dd371f90662f78a3ec034fbfea2"
integrity sha512-nrM0raOYQDWKnfvC6RQSlZtznID2Zfkg6U+RnJATeJbdKekouHbe5mmTC10nH7uxJI9hXHbKMNhyWFcImmmvjQ==
metro-transform-plugins@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.76.5.tgz#b4a49b5b55fd3bc24c5a65fa8e40ba07d84e4170"
integrity sha512-7pJ24aRuvzdQYpX/eOyodr4fnwVJP5ArNLBE1d0DOU9sQxsGplOORDTGAqw2L01+UgaSJiiwEoFMw7Z91HAS+Q==
dependencies:
"@babel/core" "^7.20.0"
"@babel/generator" "^7.20.0"
@@ -6520,28 +6609,28 @@ metro-transform-plugins@0.76.4:
"@babel/traverse" "^7.20.0"
nullthrows "^1.1.1"
metro-transform-worker@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.76.4.tgz#ee5b531e86d90f173356e93dc8465d06c36c2cb0"
integrity sha512-KvBUmgG9Z4fjbl2o6R1MZzsESIUVYw8XjfMdaBISP+yoYHoBLh841yzhCGWBc3JI8fQ86StxBMztlKCdxv0AWA==
metro-transform-worker@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.76.5.tgz#d101ad46c1a607c7bc52f0a0888961d237df42bd"
integrity sha512-xN6Kb06o9u5A7M1bbl7oPfQFmt4Kmi3CMXp5j9OcK37AFc+u6YXH8x/6e9b3Cq50rlBYuCXDOOYAWI5/tYNt2w==
dependencies:
"@babel/core" "^7.20.0"
"@babel/generator" "^7.20.0"
"@babel/parser" "^7.20.0"
"@babel/types" "^7.20.0"
babel-preset-fbjs "^3.4.0"
metro "0.76.4"
metro-babel-transformer "0.76.4"
metro-cache "0.76.4"
metro-cache-key "0.76.4"
metro-source-map "0.76.4"
metro-transform-plugins "0.76.4"
metro "0.76.5"
metro-babel-transformer "0.76.5"
metro-cache "0.76.5"
metro-cache-key "0.76.5"
metro-source-map "0.76.5"
metro-transform-plugins "0.76.5"
nullthrows "^1.1.1"
metro@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/metro/-/metro-0.76.4.tgz#e965f17d2c20a56ee7357bce68871150fe12681d"
integrity sha512-LOnlkLt6ataFzBifhhBUjHpaQo22vqfqMEpT+LMBfF9IqESJKahe5TBpQ5OsBY4LtVp9EZxKi8FvK0B4tvTx1g==
metro@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/metro/-/metro-0.76.5.tgz#0defc2a773dcdfe6569d1bd7f7a25a7424ce6f11"
integrity sha512-aEQiqNFibfx4ajUXm7Xatsv43r/UQ0xE53T3XqgZBzsxhF235tf1cl8t0giawi0RbLtDS+Fu4kg2bVBKDYFy7A==
dependencies:
"@babel/code-frame" "^7.0.0"
"@babel/core" "^7.20.0"
@@ -6563,23 +6652,24 @@ metro@0.76.4:
image-size "^1.0.2"
invariant "^2.2.4"
jest-worker "^27.2.0"
jsc-safe-url "^0.2.2"
lodash.throttle "^4.1.1"
metro-babel-transformer "0.76.4"
metro-cache "0.76.4"
metro-cache-key "0.76.4"
metro-config "0.76.4"
metro-core "0.76.4"
metro-file-map "0.76.4"
metro-inspector-proxy "0.76.4"
metro-minify-terser "0.76.4"
metro-minify-uglify "0.76.4"
metro-react-native-babel-preset "0.76.4"
metro-resolver "0.76.4"
metro-runtime "0.76.4"
metro-source-map "0.76.4"
metro-symbolicate "0.76.4"
metro-transform-plugins "0.76.4"
metro-transform-worker "0.76.4"
metro-babel-transformer "0.76.5"
metro-cache "0.76.5"
metro-cache-key "0.76.5"
metro-config "0.76.5"
metro-core "0.76.5"
metro-file-map "0.76.5"
metro-inspector-proxy "0.76.5"
metro-minify-terser "0.76.5"
metro-minify-uglify "0.76.5"
metro-react-native-babel-preset "0.76.5"
metro-resolver "0.76.5"
metro-runtime "0.76.5"
metro-source-map "0.76.5"
metro-symbolicate "0.76.5"
metro-transform-plugins "0.76.5"
metro-transform-worker "0.76.5"
mime-types "^2.1.27"
node-fetch "^2.2.0"
nullthrows "^1.1.1"
@@ -6837,10 +6927,10 @@ oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
ob1@0.76.4:
version "0.76.4"
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.76.4.tgz#3c576b363d7efd7ef2491f433fe143aa092b1390"
integrity sha512-S6qUASzl27QBmauuvC9aDkJwNqgLjMtp7AFqrm8MjpyjVYQ4p4V8zqqyMNaHnXNYl4+qB9hvUBXqFd3QOpNKig==
ob1@0.76.5:
version "0.76.5"
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.76.5.tgz#85476959743d8f6722faf0ac29bee8861f50120b"
integrity sha512-HoxZXMXNuY/eIXGoX7gx1C4O3eB4kJJMola6KoFaMm7PGGg39+AnhbgMASYVmSvP2lwU3545NyiR63g8J9PW3w==
object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
@@ -8666,6 +8756,11 @@ y18n@^5.0.5:
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yallist@^3.0.2:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"