Compare commits

...
Author SHA1 Message Date
Distiller 38465f2d18 [0.71.0-rc.2] Bump version numbers 2022-11-24 16:47:47 +00:00
Riccardo Cipolleschi aa2b243bc5 [LOCAL] Bump Podfile.lock to avoid failures when testing/in ci 2022-11-24 15:43:47 +00:00
Riccardo Cipolleschi 49c0267b66 [LOCAL] Use the right logic for build from source 2022-11-24 12:34:42 +00:00
Dmitry Rykun 0d90a44adf Remove hermesc build dir for non-Hermes build
Summary: Changelog: [iOS][Fixed] - Remove hermesc build dir for non-Hermes build.

Reviewed By: christophpurrer

Differential Revision: D41052884

fbshipit-source-id: c9e85ca06cef79fa35e81972181558d44ca93d90
2022-11-24 12:23:17 +00:00
Dmitry Rykun 1739139c7c Fix removing Copy Hermes Framework script phase
Summary: Changelog: [iOS][Fixed] - Remove `Copy Hermes Framework` script phase for non-Hermes build.

Reviewed By: hramos

Differential Revision: D41051076

fbshipit-source-id: b4b92330934e950ec3156f39f3807b90f803c1ba
2022-11-24 12:21:37 +00:00
Distiller 79f785760f [0.71.0-rc.1] Bump version numbers 2022-11-23 15:50:02 +00:00
Lorenzo Sciandra 9979e38c70 [LOCAL] remove the hermes engine cache in the clean script 2022-11-23 11:39:17 +00:00
Lorenzo Sciandra 18b847fa28 [LOCAL] bump RNGP and codegen in root package.json too 2022-11-22 16:20:46 +00:00
Riccardo Cipolleschi 8f2c7ff9f2 Remove HERMES_BUILD_FROM_SOURCE flag (#35397)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35397

This Diff removes the `HERMES_BUILD_FROM_SOURCE` that was not always propagated to the original script. This lead to some cases where hermesC was built during `pod install` and then removed by the `react_native_post_install`'s `else` branch.

Basically, when the Pods are installed the first time, everything run smoothly. Subsequent invocations of `pod install`, to install other dependencies, for example, will incur in this problem because:
1. Cocoapods will see that hermes-engine is already installed
2. the podspec is not executed, given that the pod has been fetched from the cache
3. The env var is not set (given that the podspec is not executed)
4. the main script sees the env var as not set, `ENV['HERMES_BUILD_FROM_SOURCE'] == "1"` return false
5. The `else` branch is executed, and it removes the `hermesc_build_dir` and the `copy Hermes framework` script phase.

[iOS][Changed] - Remove `HERMES_BUILD_FROM_SOURCE` flag

Reviewed By: cortinico, dmytrorykun

Differential Revision: D41373439

fbshipit-source-id: ea4aafd187c0ca3ff5c0d79f8aeaaa46ad50f499
2022-11-22 15:57:12 +00:00
Riccardo Cipolleschi a7792da695 [LOCAL] Bump Codegen and RNGP 2022-11-22 15:55:35 +00:00
Dmitry Rykun fc1dbb8f0b [LOCAL] fix copy-hermes-xcode.sh 2022-11-22 15:39:18 +00:00
Riccardo ba1a9defbb [LOCAL] bypass tag check in dry run (#35428) 2022-11-22 15:02:21 +00:00
Lorenzo Sciandra 6107793fda [LOCAL] fix removal of version from Hermes tarball, part 2 2022-11-22 14:46:46 +00:00
Riccardo Cipolleschi 78c8e49d0a Fix avoid forcing podspec versions (#35274)
Summary:
This is a backport of [this](https://github.com/facebook/react-native/commit/becb47ccb6a6ed77e81b5488561ef6d683933ffe) local fix we made on
0.71-stable.

All our podspecs delegates to the main React Native pods script to set up the dependencies properly. The React-Codegen.podspec, which is generated by
the script itself, was generated with hardcoded dependencies. This PR aligns the versioning with the other podspec.

On a side note, this could create issues in CI and when releaseing, because we are changing the versions to prepare the new release and it breaks some
steps.

## Changelog

[iOS] [Fixed] - Make sure that the React-Codegen.podspec does not enforce specific versions of its dependencies.

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

Test Plan:
1. Ruby tests are passing
2. Manually tested that pods are correctly installed in the following configurations
  - RNTester - Hermes - Old Architecture
  - RNTester - Hermes - New Architecture
  - RNTester - JSC - Old Architecture
  - RNTester - JSC - New Architecture

Reviewed By: christophpurrer

Differential Revision: D41153859

Pulled By: cipolleschi

fbshipit-source-id: 043513866a66ecca3e326f8671bea3ec576422de

# Conflicts:
#	scripts/cocoapods/codegen_utils.rb
2022-11-22 14:41:00 +00:00
Lorenzo Sciandra e809e4b1ec [LOCAL] fix removal of version from Hermes tarball 2022-11-22 13:46:26 +00:00
Lorenzo Sciandra 67c373ff3a [LOCAL] fix e2e script 2022-11-22 12:00:34 +00:00
Lorenzo Sciandra ceaebc6975 [LOCAL] update yarn lock 2022-11-22 11:42:05 +00:00
Lorenzo Sciandra 05646f8f38 [LOCAL] fix up dependency from repo-config up to root for testing on CI 2022-11-22 11:41:29 +00:00
Riccardo Cipolleschi 0ad1c53443 Improve version checks to avoid mistakes in the versioning (#35296)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35296

This change adds some version checks and enforces that every version matches some specific format based on the build type we are trying to run.

## Changelog
[General][Changed] - Improve version checks

Reviewed By: cortinico

Differential Revision: D41161756

fbshipit-source-id: 4172195c5e031c1eaf7b33bb74f381c04e9adaf5
2022-11-22 11:31:58 +00:00
Riccardo Cipolleschi c9fd1dd56e chore: fail prepare package for release if tag exists (#35305)
Summary:
This PR makes sure that the `preapre_package_for_release` script fail fast if there is already a tag for the desired version
on github.

## Changelog

[General] [Added] - Make the `prepare_package_for_release` fail if there is already a git tag with that version

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

Test Plan:
Tested manually. The script is currently only invoked during the release process.
<img width="1238" alt="Screenshot 2022-11-10 at 12 24 03" src="https://user-images.githubusercontent.com/11162307/201090947-274c1b1c-0b6a-4619-bc85-fa60e5eaeee1.png">

Reviewed By: cortinico

Differential Revision: D41403159

Pulled By: cipolleschi

fbshipit-source-id: fb87df345b14568c750482e5c68be53551a9acbb

# Conflicts:
#	scripts/release-utils.js
2022-11-22 11:31:55 +00:00
Dmitry Rykun 572ada9308 Various fixes for Hermes build-from-source behaviour
Summary:
Original title: **[RN] Do not encode path to cmake in hermes-engine Pod, build hermesc in prepare_pods**

The result of `#{%x(command -v cmake | tr -d '\n')}` was being encoded into the `hermes-engine` Pod. This can lead to conflicts in the CocoaPods cache when `pod install` is run on different machines.

Instead of running the command during `pod install`, we defer to the actual build scripts so they can find `cmake` when `$CMAKE_BINARY` is not set.

More importantly, this fixes an issue that crept into the Sandcastle CocoaPods offline mirrors, but which would only manifest itself when people run `js1 oss prepare-pods`.

RNTester would not build due to RNTesterPods.xcworkspace being configured to use cmake from an arbitrary path instead of using the cmake from $PATH.

This does not affect Sandcastle due to `CMAKE_BINARY` getting overriden in Sandcastle.
 ---

**Update** by dmytrorykun:

It is impossible to address the problem described in the original title by simply adding `CMAKE_BINARY=${CMAKE_BINARY:-cmake}` to `build-hermes-xcode.sh`. This script is supposed to run from Xcode. Since Xcode doesn't have access to system `PATH` variable, it is unable to locate `cmake`, and build fails.

However this diff contains other useful changes:

1. Remove trailing newline in `cmake` path in `build-hermes-xcode.sh`.
2. Fix inverted logic in `copy-hermes-xcode.sh`.
3. Fix typo in `remove xcuserdata` step in Sandcastle.
4. Remove unused `HERMES_DISABLE_HERMESC_BUILD`.

Changelog:
[iOS] [Fixed] - Various fixes for Hermes build-from-source behaviour.

Reviewed By: cipolleschi

Differential Revision: D41139384

fbshipit-source-id: 4a4a44a7ac201d279718d84cd02d60b4eaf3956b
2022-11-22 11:29:56 +00:00
David Angulo 362e1974fe Read .ruby-version file in Gemfile (#35410)
Summary:
When updating the Ruby version, 2 files are always needed to be updated (`.ruby-version` and `Gemfile`). When not in sync it can lead to an error like `Your Ruby version is 2.7.6, but your Gemfile specified 2.7.5`.

This lessens the files that need to be updated when upgrading the Ruby version and makes it in sync always. It makes the `.ruby-version` the source of truth.

### Example 1:

<img width="481" alt="Screenshot 2022-11-20 at 13 56 08" src="https://user-images.githubusercontent.com/36528176/202888191-450ab6d0-32a4-4d37-ad82-0beb2b22fa82.png">

When upgrading from `0.70.0` to `0.71.0-rc.0`. 2 files needs to be updated when it could have been just 1.

Source: https://react-native-community.github.io/upgrade-helper/?from=0.70.0&to=0.71.0-rc.0

### Example 2:

21c8837c12 updates 4 files (`.ruby-version`, `Gemfile`, `template/Gemfile`, `template/_ruby-version`) when it could have been just 2.

### Other Sources:
* https://andycroll.com/ruby/read-ruby-version-in-your-gemfile/
* https://render.com/docs/ruby-version (Heroku alternative)
* https://stackoverflow.com/a/35823132/9375533

## Changelog

[General] [Changed] - Read `.ruby-version` file in `Gemfile`

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

Test Plan: Only `.ruby-version` and `template/_ruby-version` needs to be updated when upgrading Ruby version.

Reviewed By: christophpurrer, cipolleschi

Differential Revision: D41429147

Pulled By: rshest

fbshipit-source-id: 9e541a1d84aed5dca1e6f465c61bb0ba15574211
2022-11-22 11:29:46 +00:00
Riccardo Cipolleschi 61baa751c9 Fix: Avoid path in the template import (#35394)
Summary:
Investigating [this comment](https://github.com/reactwg/react-native-releases/discussions/41#discussioncomment-4170008), I made some tests.
It seems like we can simply use `#import <RCTAppDelegate.h>` instead of the `#import <React-RCTAppDelegate/RCTAppDelegate.h>` in both setups:
- default setup
- `use_frameworks! :linkage => :static`

## Changelog

[iOS] [Fixed] - Support `use_framework! :linkage => :static` in template

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

Test Plan:
1. Manually tested with a new app
2. CircleCI
3. Sandcastle

Reviewed By: cortinico

Differential Revision: D41402060

Pulled By: cipolleschi

fbshipit-source-id: e1ed8196ed860b3663a88f5283f2745e39b0e944
2022-11-22 11:29:39 +00:00
Dmitry Rykun cd875420e8 Abort pod install if bad HERMES_ENGINE_TARBALL_PATH is set
Summary:
Changelog:
[iOS][Changed] - Abort pod install if bad HERMES_ENGINE_TARBALL_PATH is set.

Reviewed By: cipolleschi

Differential Revision: D41341471

fbshipit-source-id: 34a3ac154b0a3f795d07dcd10f92361cb9bb4ad6
2022-11-22 11:29:31 +00:00
Mike Hardy c36c33c613 fix(template): reference App.tsx vs App.js in template text (#35377)
Summary:
The template has moved to typescript now, the self-reference needed an update

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[GENERAL] [FIXED] - reference App.tsx vs App.js in text of new typescript template

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

Test Plan: It is just a text change - it either makes sense or it doesn't. I think it makes sense?

Reviewed By: cipolleschi

Differential Revision: D41386912

Pulled By: NickGerleman

fbshipit-source-id: 6e62c11567e8fbff70b123446a827b18af43e864
2022-11-22 11:29:23 +00:00
Nicola Corti e5fba33a94 Void the Maven coordinates for react-native and hermes-engine (#35379)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35379

This diff moves the publishing coordinates from:
```
com.facebook.react:react-native
com.facebook.react:hermes-engine
```

to

```
com.facebook.react:react-android
com.facebook.react:hermes-android
```

I've picked those they are the most layout friendly when building from source, but we can discuss if we want others.
I've updated the Gradle plugin to have a dependencySubstitution rule + update the template with those changes.

It should now be possible to still use `implementation("com.facebook.react:react-native:+")` inside libraries
on 0.71+ and RNGP will resolve dependencies correctly.

Changelog:
[Android] [Changed] - Void the Maven coordinates for react-native and hermes-engine

Reviewed By: cipolleschi

Differential Revision: D41380525

fbshipit-source-id: 91e059fa261acb89bee7ca0c79c30c3d856a2c80
2022-11-22 11:29:04 +00:00
Alpha 16c32f920e Resolve android crash on display modal (#35380)
Summary:
From exception logging, found crashes due to `Attempt to invoke virtual method 'int android.view.ViewGroup.getChildCount()' on a null object reference`. Tracing through the stack, it appears the constructor for `ViewGroup` conditionally calls `initializeScrollbarsInternal()`, which in turn calls `getChildCount()`.  However `ReactModalHostView` overrides `getChildCount()`, so `getChildCount()` is called before `ReactModalHostView` constructor completes, resulting in null reference when accessing `mHostView` from `getChildCount()`.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[Android] [Fixed] - Fix crash on initialize modal

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

Test Plan: In the rn-tester project, display a modal.

Reviewed By: javache, cipolleschi

Differential Revision: D41392235

Pulled By: ryancat

fbshipit-source-id: ce78e4d458ad41769e78139ea0a8a038384e830d
2022-11-22 11:28:55 +00:00
Nick Gerleman ea22ee6bf6 Fixup template devDependencies (#35372)
Summary:
Fixes missing/incorrect devDependencies in a newly built app. The previous set did not pull in prettier, causing linting to fail.  There was a peerDependency warning on yarn install. We also saw a separate lint warning at runtime specific to TS 4.9 being pulled in now, so we constrain in that version a bit.

Prettier and preset-env versions match the constraints and lockfiles of other RN packages.

## Changelog

[General] [Fixed] - Fixup template devDependencies

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

Test Plan:
Created a new app targeting 0.71 via `react-native init`.

1. `yarn install --force` no longer shows warnings
2. `prettier` is installed, `yarn lint` no longer fails, and shows no warnings or errors
3. ~Tentatively a test step to add tests against linting in new app, but last time doing that in CircleCI led to timeouts with no output  that I didn't have time to debug, so maybe that's fixed now? �‍♀️.~ (edit: still hangs)

Reviewed By: NickGerleman

Differential Revision: D41363021

Pulled By: lunaleaps

fbshipit-source-id: d6163b01e8934d75a231fa0fd849d7bde7b3500c
2022-11-22 11:28:46 +00:00
Riccardo Cipolleschi adfd21e035 Configure BlobModule as proper TurboModule
Summary:
This change puts back D40716048 (https://github.com/facebook/react-native/commit/279cfec55fdf404fdb9198edbb37d3adfdfb3bf1) but in the right way, i.e. modifying the script that should generate those changes.

## Changelog
[iOS][Added] - Make the blobs proper TM

Reviewed By: dmytrorykun

Differential Revision: D41312160

fbshipit-source-id: 38850a63eb8d66ffd179743b4948a23340c8782e
2022-11-22 11:28:23 +00:00
Nick Gerleman 41c56db95d Incorporate gap space into main axis overflow flag (#1173)
Summary:
X-link: https://github.com/facebook/yoga/pull/1173

In https://github.com/facebook/react-native/issues/35351 we see incorrect child item height when the flex-wrap is enabled, the cross-axis is to be stretched, and main-axis overflow is caused by gap.

In YGDistributeFreeSpaceSecondPass, if we do not have overflow (determined by flexBasisOverflows), we have stretch cross-alignment, and we reason that nothing can add to main axis dimensions, we know we're a single line and want to take full cross dimensions. and can set YGMeasureModeExactly which uses parent dimensions. Guessing an optimization?

If we do have overflow, then we set YGMeasureModeAtMost to find minimum possible cross-axis dimensions instead.

`flexBasisOverflows` incorporates both computed flex basis, and margin, so it is more generally a flag for whether we will wrap. So we should incorporate gap spacing into it. E.g. it is also used for whether we should the match main axis parent dimension of the overall container. This change does just that, and renames the flag to `mainAxisOverflows`.

We will want to cherry-pick the fix for this into RN 0.71 since we have not yet introduced the community to the incorrect behavior, and we expect a lot of usage of flex-gap.

Changelog:
[General][Fixed] - Fix incorrect height when gap causes main axis to overflow and cross-axis is stretched

Reviewed By: yungsters

Differential Revision: D41311424

fbshipit-source-id: bd0c3b5aac478a56878703b6da84fc3993cc14da
2022-11-22 11:28:11 +00:00
Adam Gleitman 8d11cb4b9c Add Dynamic Type support for iOS (Paper and Fabric) (#35017)
Summary:
This adds Dynamic Type support in iOS as described [here](https://github.com/react-native-community/discussions-and-proposals/issues/519).

`Text` elements have a new prop, `dynamicTypeRamp`, that allows users to specify which font ramp a particular `Text` element should take on as the OS's accessibility setting for text size. The different types line up with different values of `UIFontTextStyle`. If not specified, we default to the current behavior.

~~For the moment, this change is only for Paper. I tried applying a corresponding change to Fabric by adding an additional field to [`facebook::react::TextAttributes`](https://github.com/facebook/react-native/blob/main/ReactCommon/react/renderer/attributedstring/TextAttributes.h) and changing [`RCTEffectiveFontSizeMultiplierFromTextAttributes`](https://github.com/facebook/react-native/blob/afb124dcf0cdf0db525acc7cfd2cea2742c64068/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm#L79-L84) to use that new field, but in the process I discovered that this function doesn't seem to ever get called, hence [this bug](https://github.com/facebook/react-native/issues/34990).~~

## Changelog

[iOS] [Added] - Dynamic Type support

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

Test Plan:
Validated with a test page in RNTester. Screenshots follow:

A) Default text size
B) Largest non-accessibility text size
C) Largest accessibility text size, split across two screenshots due to size

| A | B | C |
|-|-|-|
| ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 17 08](https://user-images.githubusercontent.com/717674/196562746-c8bbf53d-3c70-4e55-8600-0cfed8aacf5d.png) | ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 17 55](https://user-images.githubusercontent.com/717674/196563051-68bb0e34-c573-47ed-8c19-58ae45a7ce2b.png) | ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 18 33](https://user-images.githubusercontent.com/717674/196563185-61ede5ee-e79e-4af5-84a7-8f1e230a25f8.png) |
||| ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 18 42](https://user-images.githubusercontent.com/717674/196563208-2242efa2-5f24-466d-80f5-eb57a7678a67.png) |

Reviewed By: sammy-SC

Differential Revision: D40779346

Pulled By: NickGerleman

fbshipit-source-id: efc7a8e9810a93afc82c5def97af15a2e8453d90

# Conflicts:
#	packages/rn-tester/Podfile.lock
2022-11-22 11:27:55 +00:00
Riccardo Cipolleschi 5e5d29e43c Remove version from the tarball (#35285)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35285

While doing the release 0f 0.71.0-RC0, we noticed that having the RN version in the hermes tarball was causing more harm than good.

With the version in the name, we ended up with multiple tarballs for debug and release and we were not able to explicitly pick the right tarball given a build.

This change remove the version from the tarball name.

## Changelog
[General][Changed] - Remove React Native version from Hermes tarball name

Reviewed By: lunaleaps

Differential Revision: D41156353

fbshipit-source-id: 8899d5e1e1555bc728d923f3b78d1261e6ff09c7
2022-11-22 11:24:26 +00:00
Lorenzo Sciandra 3624b47768 Revert "[Fix] Make sure to export a single version for hermes artifacts and wipe Podfile.lock while in release"
This reverts commit 41bf725ada.
2022-11-22 11:23:51 +00:00
Kacper Kafara 99bcbad2b2 Fix variable expansion in ReactNative-application.cmake (#35306)
Summary:
Hi, while adjusting [react-native-screens](https://github.com/software-mansion/react-native-screens) to `0.71.0-rc.0` I encountered the same problems as reported [here](https://github.com/reactwg/react-native-releases/discussions/41#discussioncomment-4085694) by WoLewicki.

Basically inside `CMake`'s `foreach` loop iterator variable is not being expanded to the actual value:

```cmake
foreach(autolinked_library ${AUTOLINKED_LIBRARIES})
    target_link_libraries(autolinked_library common_flags) // <-- here we are literally linking to "autolinked_library".
endforeach()
```

## Changelog

[Android] [Fixed] - Fix Android autolinking failing because of not expanded variable

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

Reviewed By: christophpurrer, cipolleschi

Differential Revision: D41220408

Pulled By: rshest

fbshipit-source-id: 12ce993f0c5227ca7d3c2cc272fe3739126930b3
2022-11-22 11:16:52 +00:00
Lorenzo Sciandra 4eda46f7f5 deps(cli): "backport" CLI bump into main from 0.71 (#35260)
Summary:
This is just a PR to realign main branch (and put it ahead) of a local change we did in 0.71: https://github.com/facebook/react-native/commit/741d10247601997debdf9197f75774830fe04ae5

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[General] [Changed] - Bump CLI to v10 alpha5

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

Test Plan: N/A

Reviewed By: christophpurrer

Differential Revision: D41122011

Pulled By: cipolleschi

fbshipit-source-id: 8f01ed94bfd39d58b2e54cd2945fcca5bb8ebd18

# Conflicts:
#	package.json
#	yarn.lock
2022-11-22 11:16:35 +00:00
Christoph Purrer 08430bf214 react-native code-gen > C++ TurboModules struct support (#35265)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35265

This adds a templating layer for C++ TurboModules to automatically generate struct templates from TurboModule specs.

You have to define concrete types for those templates to use them in your C++ TurboModule.

E.g. for the JS flow type:
```
export type ObjectStruct = {|
  a: number,
  b: string,
  c?: ?string,
|};
```
code-gen will now generate the following template code:
```
#pragma mark - NativeCxxModuleExampleCxxBaseObjectStruct

template <typename P0, typename P1, typename P2>
struct NativeCxxModuleExampleCxxBaseObjectStruct {
  P0 a;
  P1 b;
  P2 c;
  bool operator==(const NativeCxxModuleExampleCxxBaseObjectStruct &other) const {
    return a == other.a && b == other.b && c == other.c;
  }
};

template <typename P0, typename P1, typename P2>
struct NativeCxxModuleExampleCxxBaseObjectStructBridging {
  static NativeCxxModuleExampleCxxBaseObjectStruct<P0, P1, P2> fromJs(
      jsi::Runtime &rt,
      const jsi::Object &value,
      const std::shared_ptr<CallInvoker> &jsInvoker) {
    NativeCxxModuleExampleCxxBaseObjectStruct<P0, P1, P2> result{
      bridging::fromJs<P0>(rt, value.getProperty(rt, "a"), jsInvoker),
      bridging::fromJs<P1>(rt, value.getProperty(rt, "b"), jsInvoker),
      bridging::fromJs<P2>(rt, value.getProperty(rt, "c"), jsInvoker)};
    return result;
  }

  static jsi::Object toJs(
      jsi::Runtime &rt,
      const NativeCxxModuleExampleCxxBaseObjectStruct<P0, P1, P2> &value) {
    auto result = facebook::jsi::Object(rt);
    result.setProperty(rt, "a", bridging::toJs(rt, value.a));
    result.setProperty(rt, "b", bridging::toJs(rt, value.b));
    if (value.c) {
      result.setProperty(rt, "c", bridging::toJs(rt, value.c.value()));
    }
    return result;
  }
};
```
and you can use it in our C++ TurboModule for example as:
```
using ObjectStruct = NativeCxxModuleExampleCxxBaseObjectStruct<
    int32_t,
    std::string,
    std::optional<std::string>>;

template <>
struct Bridging<ObjectStruct>
    : NativeCxxModuleExampleCxxBaseObjectStructBridging<
          int32_t,
          std::string,
          std::optional<std::string>> {};
```
or as
```
using ObjectStruct = NativeCxxModuleExampleCxxBaseObjectStruct<
    float,
    folly::StringPiece,
    std::optional<std::string>>;

template <>
struct Bridging<ObjectStruct>
    : NativeCxxModuleExampleCxxBaseObjectStructBridging<
          float,
          folly::StringPiece,
          std::optional<std::string>> {};
```
Or as
...

Changelog: [Internal]

Reviewed By: rshest

Differential Revision: D41133761

fbshipit-source-id: fdf36e51073cb46c5234f6121842c79a884899c7
2022-11-22 11:15:24 +00:00
Ruslan Lesiutin adcdb366da refactor(react-native-github): move ImagePickerIOS to internal (#35199)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35199

**Changelog:**
[iOS][Removed] - Removed ImagePickerIOS module native sources
[JS][Removed] - Removed ImagePickerIOS module from react-native

Reviewed By: cortinico

Differential Revision: D40859520

fbshipit-source-id: a6a114a05574d46ea62600999bff95025ba7cdc8
2022-11-22 11:15:16 +00:00
Pieter De Baets df737b09b1 Fix Cpp codegen handling of optional arguments
Summary:
Changelog:
[General][Fixed] - Codegen for C++ TurboModules of optional method arguments was incorrect

Reviewed By: christophpurrer

Differential Revision: D40979066

fbshipit-source-id: 5bb48dbafc14dcea21b7e0b15e3f4bb527bc8476
2022-11-22 11:15:07 +00:00
Ruslan Shestopalyuk b310f2b078 Scaffolding for the PerformanceObserver TurboModule (C++ side) (#35226)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35226

Changelog: [Internal]

This adds scaffolding for the C++ side of NativePerformanceObserver module.

Thanks to christophpurrer for helping set this up, as this is the first one of this kind inside core/OSS.

Reviewed By: rubennorte

Differential Revision: D41028555

fbshipit-source-id: 4acf0e71a254a42044cbbe5f94f40938342c6aa2
2022-11-22 11:14:01 +00:00
Ruslan Shestopalyuk ea0cd5b7ca JS side implementation of PerformanceObserver API
Summary:
[Changelog][Internal]

This adds module specs for the native part of PerformanceObserver, as well as the interaction logic vs the NativePerformanceObserver API.

See https://fb.quip.com/MdqgAk1Eb2dV for more detail.

Reviewed By: rubennorte

Differential Revision: D40897006

fbshipit-source-id: 77475f21dad9ee9dbe15df5a989eb08d314e6db2
2022-11-22 11:13:38 +00:00
Ruslan Shestopalyuk d02b51332e Refactor PerformanceObserver public API
Summary:
Changelog: [Internal]

This is a follow-up to D40892974 (https://github.com/facebook/react-native/commit/a671d61b6de5f106e9fd803a73fddb4b6fa6656b), addressing the post-land comments and discussions.

Reviewed By: rubennorte

Differential Revision: D40979654

fbshipit-source-id: 2e7e1d24be8211cc3363a07678745039e5606d8d
2022-11-22 11:13:25 +00:00
Ruslan Shestopalyuk 8c488d8757 Exclude PerformanceObserver from flow/haste
Summary:
[Changelog][Internal]

This is to prevent an accidental use of PerformanceObserver while it's still a work in progress.

PerformanceObserver is also moved into a dedicated folder, `Libraries/WebPerformance`.

Reviewed By: rubennorte

Differential Revision: D40978749

fbshipit-source-id: 09645a95bed72902870ebc00c1b4a3d81ab4c829
2022-11-22 11:13:19 +00:00
Christoph Purrer c63ea4c3a0 react-native code-gen > Add a C++ only TurboModule example (for Android/iOS/macOS/Windows) (#35138)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35138

Changelog:

[General][Added] - Add a C++ only TurboModule example (for Android/iOS/macOS/Windows)

react-native@0.69 introduced a new bridging layer to ease integration for pure C++ TurboModules using C++ std:: types directly instead of the lower level jsi:: types:
https://github.com/facebook/react-native/tree/v0.69.0/ReactCommon/react/bridging

This bridging layer can be used in JSI functions or more conveniently in C++ TurboModules.

Here is a example of an C++ only TurboModule which will work on Android and iOS and macOS/Windows (using microsoft/react-native-macos|windows) only using flow/TypeScript and standard C++ types.

C++ only TurboModules are very handy as they do not require to work with JSI APIs - instead std:: or custom C++ can by used.

Reviewed By: javache

Differential Revision: D39011736

fbshipit-source-id: 84c833d8540671fde8505f1aeb0265074b248730
2022-11-22 11:09:47 +00:00
Oleksandr Melnykov d587e0c2a5 Bump OSS Android build to SDK 33 (#35196)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35196

Changelog:
[Android][Changed] - Bump Android compile and target SDK to 33

Reviewed By: cortinico

Differential Revision: D41007003

fbshipit-source-id: e7866107fdcfafa778faa6c7f31835b8dd15647a
2022-11-22 11:09:37 +00:00
Riccardo Cipolleschi 79bb531416 fix: Change checkout cache strategy (#35259)
Summary:
This PR updates he cache strategy for the `checkout_with_cache command`.

The previous strategy was using three keys in descending priority order to restore from the cache:
* `<< parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-{{ .Revision }}`
* `<< parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}`
*`<< parameters.checkout_base_cache_key >>-{{ arch }}`

When it saves, it always saves using the first key.

The restore works as it follows:
1. It tries to restore the cache using the first key
2. If it fails, it checks whether there is a cache hit for a key that matches the second key as a pattern
3. If it fails, it checks whether there is a cache hit for a key that matches the third pattern
4. Otherwise, it is a cache miss.

This does not work well. Imagine that you submit some code in commit `xxxx` for branch `abc`.
The CI run the first time, it misses all the three keys and checks out the code normally.
Then, it stores the checked out code in the `checkout_key-abc-xxxx` key.

Then, you submit a commit `yyyy` in the same branch.
The CI starts, it tries with the key `checkout_key-abc-yyyy` but it misses
It tries with the key `checkout_key-abc` and it finds the cache for `checkout_key-abc-xxxx` and it restores it, forgetting about your changes.

While doing the release, we created a tag in a commit X. Then we manually had to remove it, but the CI had a cached version of .git with the tag for
the `0.71-stable` branch. And the release failed because the tag was already existing.

### Why this should work

With this solution, we are going to cache using the commit. If there is no cache for a specific commit, it will be a miss. It won't try to be smart and
retrieve the code from previous caches.

This should prevent stale caches and if we manually remove a tag, and then we do a new commit, it should work.

This is a good trade-off that allows to pay the checkout cost only for the first batch of jobs of the pipeline.

**NOTE:** This still won't work if we don't do a new commit.

## Changelog

[General] [Fixed] - Change Cache strategy to avoid cache bumps in Release

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

Test Plan: 1. CircleCI must be green

Reviewed By: jacdebug

Differential Revision: D41120895

Pulled By: cipolleschi

fbshipit-source-id: 2b45da01803197dbe4a25a313a9dfc53a976d096
2022-11-22 11:09:16 +00:00
Christoph Purrer 775d5cd00c Provide easy registration of C++ TurboModules in rn-tester Android (#35225)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35225

Changelog:
[Android] [Changed] - Provide easy registration of C++ TurboModules in rn-tester Android

Reviewed By: javache

Differential Revision: D41069277

fbshipit-source-id: 450de9302df2916acf324d4c316996b185b2833f
2022-11-22 11:09:00 +00:00
Christoph Purrer 7ef7d99f1c TurboModules: Simplify React-bridging usage (#35212)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35212

A previous change - https://github.com/facebook/react-native/pull/34011 - already fixed basic usage of <react/bridging/.../ imports.
However that change was only tailored towards the usage of: <react/bridging/CallbackWrapper.h>
Any other header besides <react/bridging/CallbackWrapper.h> from <react/bridging/... can't be imported at this time in Xcode ... ... which is bad.

For C++ TurboModules we need to be able to access *any* <react/bridging/...> header via the React-Codegen CocoaPod.
Hence adding bridging now as a sub-spec to the ReactCommon CocoaPod

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D41057878

fbshipit-source-id: 83c117bc5252d84dd419cdb72f145f65547d23b2

# Conflicts:
#	scripts/cocoapods/__tests__/codegen_utils-test.rb
2022-11-22 11:08:31 +00:00
Christoph Purrer 83c8163540 react-native-codegen: Enable C++ TurboModule generation in OpenSource builds (#35211)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35211

This enables the generation of C++ TurboModule specs in addition to existing Java/ObjC ones.

An example is shown in https://github.com/facebook/react-native/pull/35138

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D41057630

fbshipit-source-id: 303881a63eb82f0fe8dfe10e533043a6eedb3d11
2022-11-22 11:05:56 +00:00
Riccardo Cipolleschi 229be89121 This reverts commit 2c26c8fded.
We need to pick the commits in the same order they were committed on main.
2022-11-17 10:22:48 +00:00
Nick Gerleman 2c26c8fded Incorporate gap space into main axis overflow flag (#1173)
Summary:
X-link: https://github.com/facebook/yoga/pull/1173

In https://github.com/facebook/react-native/issues/35351 we see incorrect child item height when the flex-wrap is enabled, the cross-axis is to be stretched, and main-axis overflow is caused by gap.

In YGDistributeFreeSpaceSecondPass, if we do not have overflow (determined by flexBasisOverflows), we have stretch cross-alignment, and we reason that nothing can add to main axis dimensions, we know we're a single line and want to take full cross dimensions. and can set YGMeasureModeExactly which uses parent dimensions. Guessing an optimization?

If we do have overflow, then we set YGMeasureModeAtMost to find minimum possible cross-axis dimensions instead.

`flexBasisOverflows` incorporates both computed flex basis, and margin, so it is more generally a flag for whether we will wrap. So we should incorporate gap spacing into it. E.g. it is also used for whether we should the match main axis parent dimension of the overall container. This change does just that, and renames the flag to `mainAxisOverflows`.

We will want to cherry-pick the fix for this into RN 0.71 since we have not yet introduced the community to the incorrect behavior, and we expect a lot of usage of flex-gap.

Changelog:
[General][Fixed] - Fix incorrect height when gap causes main axis to overflow and cross-axis is stretched

Reviewed By: yungsters

Differential Revision: D41311424

fbshipit-source-id: bd0c3b5aac478a56878703b6da84fc3993cc14da
2022-11-16 10:51:15 -08:00
Distiller 60129ab7ac [0.71.0-rc.0] Bump version numbers 2022-11-04 15:25:07 +00:00
Lorenzo Sciandra 41a80f2ee2 [LOCAL] Bump git checkout cache key (fourth time) 2022-11-04 15:15:19 +00:00
Lorenzo Sciandra 94b1165a44 Revert "[0.71.0-rc.0] Bump version numbers"
This reverts commit 27c32b2d71.
2022-11-04 15:14:34 +00:00
Nicola Corti e4f23f4783 [LOCAL] Invoke closeAndReleaseSonatypeStagingRepository in the publish gradle invocation 2022-11-04 08:13:54 -07:00
Distiller 27c32b2d71 [0.71.0-rc.0] Bump version numbers 2022-11-04 14:31:20 +00:00
Lorenzo Sciandra 5c9f160764 [LOCAL] Bump git checkout cache key (third time) 2022-11-04 14:26:59 +00:00
Lorenzo Sciandra 4d0be144bf Revert "[0.71.0-rc.0] Bump version numbers"
This reverts commit ea9dd430a6.
2022-11-04 14:26:17 +00:00
Lorenzo Sciandra 32931b19b1 [LOCAL] better fix for param 2022-11-04 13:14:37 +00:00
Distiller ea9dd430a6 [0.71.0-rc.0] Bump version numbers 2022-11-04 12:33:34 +00:00
Lorenzo Sciandra c4a7e46976 Revert "[0.71.0-rc.0] Bump version numbers"
This reverts commit c9a3c5749b.
2022-11-04 12:28:15 +00:00
Lorenzo Sciandra b8f8ac0e1c [LOCAL] Bump git checkout cache key (again) 2022-11-04 12:27:23 +00:00
Lorenzo Sciandra 8e3b62019e [LOCAL] remove unneed/obsolete job 2022-11-04 12:25:44 +00:00
Lorenzo Sciandra 0f72abfc03 [LOCAL] fix publish npm post strict 2022-11-04 12:25:14 +00:00
Distiller c9a3c5749b [0.71.0-rc.0] Bump version numbers 2022-11-04 11:27:06 +00:00
Riccardo Cipolleschi fd5e282290 [LOCAL] Bump git checkout cache key 2022-11-04 11:18:06 +00:00
Riccardo Cipolleschi 39798cfa91 Revert "[0.71.0-rc.0] Bump version numbers"
This reverts commit f0054e1e30.
2022-11-04 10:53:57 +00:00
Lorenzo Sciandra 741d102476 [LOCAL] bump CLI to 10 alpha3 2022-11-04 10:45:48 +00:00
Lorenzo Sciandra 49278df494 fix (deps): add explicitly eslint config to dependencies (#35192)
Summary:
Basically since this change https://github.com/facebook/react-native/pull/34423 everything worked ok because in the main branch where the monorepo has the workspace section and everything, `react-native-community/eslint-config` was getting pulled in as a node_module anyway - but when moving to a stable branch and wanting to do a release, as we are now with 0.71, because of what the final package.json looks like for react-native and [the modifications that it goes through](https://github.com/facebook/react-native/commit/f0054e1e303e238d40970d23a3b3ae47502c32ea#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519) (ex. the `workspace` section disappears), the fact that it's not directly listed as dependency makes [the CI fails](https://app.circleci.com/pipelines/github/facebook/react-native/17124/workflows/54a4162d-f466-4eab-94ba-ec9fe77e2ecf/jobs/339643) with `Error: Failed to load config "react-native-community" to extend from.`

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[General] [Fixed] - add explicitly eslint config to dependencies

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

Test Plan: In 0.71, add the deps to see the error disappear (it gets replaced by a different one though, looking into that)

Reviewed By: jacdebug, cortinico

Differential Revision: D40988407

Pulled By: cipolleschi

fbshipit-source-id: 38f433a0b4b47a7cb61b59e887459d11182a5b4b
2022-11-04 10:35:55 +00:00
Nicola Corti e59cf2db64 Remove project.android block from rn-tester's CLI config (#35197)
Summary:
The project.android block is unnecessary and contains a wrong path. Let's use the default path which is `./android`.

## Changelog

[Internal] - Remove project.android block from rn-tester's CLI config

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

Test Plan: Tested locally + will wait for a CI run

Reviewed By: robhogan

Differential Revision: D41013193

Pulled By: cortinico

fbshipit-source-id: 5c76c9b571b23ad71a23a8f3f05a9acb4d6e20b9
2022-11-04 10:24:34 +00:00
Dmitry Rykun ae677efb57 Bump dependency versions before the branch cut 0.71.0
Summary: Changelog: [General][Changed] - Bump dependency versions.

Reviewed By: cipolleschi

Differential Revision: D40991336

fbshipit-source-id: 71c8edbeb274d095403b2f17e60f217d16fe01c0
2022-11-04 08:16:36 +00:00
Riccardo Cipolleschi 41bf725ada [Fix] Make sure to export a single version for hermes artifacts and wipe Podfile.lock while in release 2022-11-03 22:39:05 +00:00
Riccardo Cipolleschi becb47ccb6 [Fix] Let React Native decide the Hermes version to use in the Codegen 2022-11-03 21:50:47 +00:00
Distiller f0054e1e30 [0.71.0-rc.0] Bump version numbers 2022-11-03 14:45:25 +00:00
Nicola Corti 936d69e7a1 Correctly set -DCMAKE_BUILD_TYPE for Hermes on iOS
Summary:
We accidentally added `-DCMAKE_BUILD_TYPE=Debug` for Hermes which is causing
a really slow engine execution. This fixes it and keep the -DCMAKE_BUILD_TYPE
aligned with the one used on Android.

Changelog:
[iOS] [Fixed] - Correctly set -DCMAKE_BUILD_TYPE for Hermes on iOS

Reviewed By: hramos, cipolleschi

Differential Revision: D40980934

fbshipit-source-id: 30f0455990a911b51eb109bebca8272507302650
2022-11-03 14:37:54 +00:00
Riccardo 151498a122 Merge pull request #35188 from dmytrorykun/export-D40979350
Revert: make RCTBlobManager TurboModule-compatible
2022-11-03 14:31:24 +00:00
Dmitry Rykun 94cea1edda feat: make RCTBlobManager TurboModule-compatible
Summary:
This diff reverts D40716048 (https://github.com/facebook/react-native/commit/279cfec55fdf404fdb9198edbb37d3adfdfb3bf1) (https://github.com/facebook/react-native/pull/35047) which breaks RCTImageLoader.
https://pxl.cl/2jKrM
Those files are auto-generated and are not supposed to be edited manually.
Changelog: [iOS] [Fixed] - https://github.com/facebook/react-native/pull/35047 reverted.

Reviewed By: cipolleschi

Differential Revision: D40979350

fbshipit-source-id: ece2b9c653fe01e209a523e6a99e41a0605fddac
2022-11-03 05:13:04 -07:00
Riccardo Cipolleschi 5f656e98c9 Hermes version bump for 0.71.0-RC0 2022-11-03 10:25:22 +00:00
128 changed files with 3732 additions and 3402 deletions
+1 -1
View File
@@ -14,7 +14,7 @@
# and build a Android application that can be used to run the
# tests specified in the scripts/ directory.
#
FROM reactnativecommunity/react-native-android:6.0
FROM reactnativecommunity/react-native-android:6.1
LABEL Description="React Native Android Test Image"
LABEL maintainer="Héctor Ramos <hector@fb.com>"
+24 -62
View File
@@ -48,15 +48,15 @@ references:
# Anchors for the cache keys
cache_keys:
checkout_cache_key: &checkout_cache_key v1-checkout
checkout_cache_key: &checkout_cache_key v5-checkout
gems_cache_key: &gems_cache_key v1-gems-{{ checksum "Gemfile.lock" }}
gradle_cache_key: &gradle_cache_key v1-gradle-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "ReactAndroid/gradle.properties" }}
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" }}
hermes_workspace_release_cache_key: &hermes_workspace_release_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-release-{{ checksum "/tmp/hermes/hermesversion" }}
hermes_windows_cache_key: &hermes_windows_cache_key v3-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "tmp/hermes/hermesversion" }}
hermes_tarball_debug_cache_key: &hermes_tarball_debug_cache_key v2-hermes-tarball-debug-{{ checksum "/tmp/hermes/hermesversion" }}
hermes_tarball_release_cache_key: &hermes_tarball_release_cache_key v1-hermes-tarball-release-{{ checksum "/tmp/hermes/hermesversion" }}
hermes_tarball_debug_cache_key: &hermes_tarball_debug_cache_key v3-hermes-tarball-debug-{{ checksum "/tmp/hermes/hermesversion" }}
hermes_tarball_release_cache_key: &hermes_tarball_release_cache_key v2-hermes-tarball-release-{{ checksum "/tmp/hermes/hermesversion" }}
pods_cache_key: &pods_cache_key v8-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }}
windows_yarn_cache_key: &windows_yarn_cache_key v1-win-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }}
yarn_cache_key: &yarn_cache_key v5-yarn-cache-{{ .Environment.CIRCLE_JOB }}
@@ -102,7 +102,7 @@ executors:
reactnativeandroid:
<<: *defaults
docker:
- image: reactnativecommunity/react-native-android:6.0
- image: reactnativecommunity/react-native-android:6.1
resource_class: "xlarge"
environment:
- TERM: "dumb"
@@ -132,10 +132,7 @@ commands:
type: string
steps:
- restore_cache:
keys:
- << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-{{ .Revision }}
- << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-
- << parameters.checkout_base_cache_key >>-{{ arch }}-
key: << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-{{ .Revision }}
- checkout
- save_cache:
key: << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-{{ .Revision }}
@@ -306,8 +303,8 @@ commands:
exit 0
fi
TARBALL_FILENAME=$(node ~/react-native/scripts/hermes/get-tarball-name.js --buildType "<< parameters.flavor >>" --releaseVersion "*")
TARBALL_PATH=$(ls $HERMES_TARBALL_ARTIFACTS_DIR/$TARBALL_FILENAME)
TARBALL_FILENAME=$(node ~/react-native/scripts/hermes/get-tarball-name.js --buildType "<< parameters.flavor >>")
TARBALL_PATH=$HERMES_TARBALL_ARTIFACTS_DIR/$TARBALL_FILENAME
echo "Looking for $TARBALL_FILENAME in $HERMES_TARBALL_ARTIFACTS_DIR"
echo "$TARBALL_PATH"
@@ -855,7 +852,9 @@ jobs:
- run:
name: Set HERMES_ENGINE_TARBALL_PATH
command: |
echo "export HERMES_ENGINE_TARBALL_PATH=$(ls -AU $HERMES_WS_DIR/hermes-runtime-darwin/hermes-runtime-darwin-*.tar.gz | head -1)" >> $BASH_ENV
BUILD_TYPE="<< parameters.flavor >>"
TARBALL_FILENAME=$(node ./scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE")
echo "export HERMES_ENGINE_TARBALL_PATH=$HERMES_WS_DIR/hermes-runtime-darwin/$TARBALL_FILENAME" >> $BASH_ENV
- run:
name: Create iOS template project
command: |
@@ -967,8 +966,8 @@ jobs:
environment:
- ANDROID_HOME: "C:\\Android\\android-sdk"
- ANDROID_NDK: "C:\\Android\\android-sdk\\ndk\\20.1.5948944"
- ANDROID_BUILD_VERSION: 31
- ANDROID_TOOLS_VERSION: 31.0.0
- ANDROID_BUILD_VERSION: 33
- ANDROID_TOOLS_VERSION: 33.0.0
- GRADLE_OPTS: -Dorg.gradle.daemon=false
steps:
- checkout_code_with_cache
@@ -1227,20 +1226,13 @@ jobs:
TARBALL_OUTPUT_DIR=$(mktemp -d /tmp/hermes-tarball-output-XXXXXXXX)
# get_release_version() is defined in build-apple-framework.sh
pushd ./sdks/hermes || exit 1
BUILD_TYPE=$BUILD_TYPE source ./utils/build-apple-framework.sh
RELEASE_VERSION=$(get_release_version)
popd
TARBALL_FILENAME=$(node ./scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE" --releaseVersion "$RELEASE_VERSION")
TARBALL_FILENAME=$(node ./scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE")
echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type"
TARBALL_OUTPUT_PATH=$(node ./scripts/hermes/create-tarball.js \
--inputDir ./sdks/hermes \
--buildType "$BUILD_TYPE" \
--releaseVersion "$RELEASE_VERSION" \
--outputDir $TARBALL_OUTPUT_DIR)
echo "Hermes tarball saved to $TARBALL_OUTPUT_PATH"
@@ -1371,7 +1363,14 @@ jobs:
- run:
name: "Set new react-native version and commit changes"
command: |
node ./scripts/prepare-package-for-release.js -v << parameters.version >> -l << parameters.latest >> --dry-run << parameters.dryrun >>
VERSION=<< parameters.version >>
if [[ -z "$VERSION" ]]; then
VERSION=$(grep '"version"' package.json | cut -d '"' -f 4 | head -1)
echo "Using the version from the package.json: $VERSION"
fi
node ./scripts/prepare-package-for-release.js -v "$VERSION" -l << parameters.latest >> --dry-run << parameters.dryrun >>
build_npm_package:
parameters:
@@ -1409,8 +1408,8 @@ jobs:
cp -r $HERMES_WS_DIR/win64-bin/* ./sdks/hermesc/win64-bin/.
cp -r $HERMES_WS_DIR/linux64-bin/* ./sdks/hermesc/linux64-bin/.
mkdir -p ./ReactAndroid/external-artifacts/artifacts/
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-runtime-darwin-debug-*.tar.gz ./ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-runtime-darwin-release-*.tar.gz ./ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz ./ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz
cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz ./ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz
- run_yarn
- download_gradle_dependencies
@@ -1495,43 +1494,6 @@ jobs:
-d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${CIRCLE_TAG:1}\" }}"
# END: Stable releases
# START: Stables and commitlies
- when:
condition:
or:
- equal: [ "release", << parameters.release_type >> ]
- equal: [ "dry-run", << parameters.release_type >> ]
steps:
- run:
name: Install dependencies
command: apt update && apt install -y jq jo
- run:
name: Create draft GitHub Release and upload Hermes binaries
command: |
RELEASE_VERSION=$(cat build/.version)
if [[ << parameters.release_type >> == "release" ]]; then
GIT_TAG=$CIRCLE_TAG
elif [[ << parameters.release_type >> == "dry-run" ]]; then
GIT_TAG=v1000.0.0
fi
ARTIFACTS=("")
for build_type in "Debug" "Release"; do
TARBALL_FILENAME=$(node ./scripts/hermes/get-tarball-name.js \
--buildType $build_type \
--releaseVersion $RELEASE_VERSION)
ARTIFACTS+=("$HERMES_WS_DIR/hermes-runtime-darwin/$TARBALL_FILENAME")
done
./scripts/circleci/create_github_release.sh \
<< parameters.release_type >> \
$GIT_TAG \
$RELEASE_VERSION \
$GITHUB_TOKEN \
"${ARTIFACTS[@]}"
# END: Stable and commitlies
# -------------------------
# JOBS: Nightly
# -------------------------
@@ -1688,7 +1650,7 @@ workflows:
jobs:
- prepare_package_for_release:
name: prepare_package_for_release
version: 'v1000.0.1'
version: ''
latest : false
dryrun: true
- prepare_hermes_workspace:
+29
View File
@@ -10,6 +10,9 @@ load(
)
load(
"//tools/build_defs/oss:rn_defs.bzl",
"ANDROID",
"APPLE",
"CXX",
"HERMES_BYTECODE_VERSION",
"IOS",
"RCT_IMAGE_DATA_DECODER_SOCKET",
@@ -264,6 +267,7 @@ REACT_PUBLIC_HEADERS = {
"React/RCTDevLoadingViewProtocol.h": RCTDEVSUPPORT_PATH + "RCTDevLoadingViewProtocol.h",
"React/RCTDevLoadingViewSetEnabled.h": RCTDEVSUPPORT_PATH + "RCTDevLoadingViewSetEnabled.h",
"React/RCTDisplayLink.h": RCTBASE_PATH + "RCTDisplayLink.h",
"React/RCTDynamicTypeRamp.h": RCTLIB_PATH + "Text/Text/RCTDynamicTypeRamp.h",
"React/RCTErrorCustomizer.h": RCTBASE_PATH + "RCTErrorCustomizer.h",
"React/RCTErrorInfo.h": RCTBASE_PATH + "RCTErrorInfo.h",
# NOTE: RCTEventDispatcher.h is exported from CoreModules:CoreModulesApple
@@ -1453,3 +1457,28 @@ rn_xplat_cxx_library2(
"//fbobjc/VendorLib/react-native-maps:react-native-maps",
],
)
rn_xplat_cxx_library2(
name = "RCTWebPerformance",
srcs = glob([
"Libraries/WebPerformance/**/*.cpp",
]),
header_namespace = "",
exported_headers = subdir_glob(
[("Libraries/WebPerformance", "*.h")],
prefix = "RCTWebPerformance",
),
fbandroid_compiler_flags = [
"-fexceptions",
"-frtti",
],
labels = [
"depslint_never_remove",
"pfh:ReactNative_CommonInfrastructurePlaceholder",
],
platforms = (ANDROID, APPLE, CXX),
visibility = ["PUBLIC"],
deps = [
":FBReactNativeSpecJSI",
],
)
+1 -1
View File
@@ -1,6 +1,6 @@
source 'https://rubygems.org'
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby '2.7.6'
ruby File.read(File.join(__dir__, '.ruby-version')).strip
gem 'cocoapods', '~> 1.11', '>= 1.11.3'
+4 -4
View File
@@ -56,7 +56,7 @@ GEM
colored2 (3.1.2)
concurrent-ruby (1.1.10)
escape (0.0.4)
ethon (0.15.0)
ethon (0.16.0)
ffi (>= 1.15.0)
ffi (1.15.5)
fourflusher (2.3.1)
@@ -85,16 +85,16 @@ GEM
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
zeitwerk (2.6.0)
zeitwerk (2.6.6)
PLATFORMS
ruby
DEPENDENCIES
cocoapods (~> 1.11, >= 1.11.2)
cocoapods (~> 1.11, >= 1.11.3)
RUBY VERSION
ruby 2.7.5p203
ruby 2.7.6p219
BUNDLED WITH
2.3.22
+3 -3
View File
@@ -10,8 +10,8 @@
*/
exports.version = {
major: 1000,
minor: 0,
major: 0,
minor: 71,
patch: 0,
prerelease: null,
prerelease: 'rc.2',
};
-48
View File
@@ -1,48 +0,0 @@
/**
* 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
*/
export interface OpenCameraDialogOptions {
/** Defaults to false */
videoMode?: boolean | undefined;
}
export interface OpenSelectDialogOptions {
/** Defaults to true */
showImages?: boolean | undefined;
/** Defaults to false */
showVideos?: boolean | undefined;
}
/** [imageURL|tempImageTag, height, width] */
export type ImagePickerResult = [string, number, number];
export interface ImagePickerIOSStatic {
canRecordVideos(callback: (value: boolean) => void): void;
canUseCamera(callback: (value: boolean) => void): void;
openCameraDialog(
config: OpenCameraDialogOptions,
successCallback: (args: ImagePickerResult) => void,
cancelCallback: (args: any[]) => void,
): void;
openSelectDialog(
config: OpenSelectDialogOptions,
successCallback: (args: ImagePickerResult) => void,
cancelCallback: (args: any[]) => void,
): void;
}
/**
* ImagePickerIOS has been extracted from react-native core and will be removed in a future release.
* Please upgrade to use either `@react-native-community/react-native-image-picker` or 'expo-image-picker'.
* If you cannot upgrade to a different library, please install the deprecated `@react-native-community/image-picker-ios` package.
* @see https://github.com/react-native-community/react-native-image-picker-ios
* @deprecated
*/
export const ImagePickerIOS: ImagePickerIOSStatic;
export type ImagePickerIOS = ImagePickerIOSStatic;
-103
View File
@@ -1,103 +0,0 @@
/**
* 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
* @flow strict-local
*/
import NativeImagePickerIOS from './NativeImagePickerIOS';
import invariant from 'invariant';
const ImagePickerIOS = {
canRecordVideos: function (callback: (result: boolean) => void): void {
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
return NativeImagePickerIOS.canRecordVideos(callback);
},
canUseCamera: function (callback: (result: boolean) => void): void {
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
return NativeImagePickerIOS.canUseCamera(callback);
},
openCameraDialog: function (
config: $ReadOnly<{|
unmirrorFrontFacingCamera?: boolean,
videoMode?: boolean,
|}>,
successCallback: (imageURL: string, height: number, width: number) => void,
cancelCallback: () => void,
): void {
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
var newConfig = {
videoMode: true,
unmirrorFrontFacingCamera: false,
};
if (config.videoMode != null) {
newConfig.videoMode = config.videoMode;
}
if (config.unmirrorFrontFacingCamera != null) {
newConfig.unmirrorFrontFacingCamera = config.unmirrorFrontFacingCamera;
}
return NativeImagePickerIOS.openCameraDialog(
newConfig,
successCallback,
cancelCallback,
);
},
openSelectDialog: function (
config: $ReadOnly<{|
showImages?: boolean,
showVideos?: boolean,
|}>,
successCallback: (imageURL: string, height: number, width: number) => void,
cancelCallback: () => void,
): void {
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
var newConfig = {
showImages: true,
showVideos: false,
};
if (config.showImages != null) {
newConfig.showImages = config.showImages;
}
if (config.showVideos != null) {
newConfig.showVideos = config.showVideos;
}
return NativeImagePickerIOS.openSelectDialog(
newConfig,
successCallback,
cancelCallback,
);
},
/**
* In iOS 13, the video URLs returned by the Image Picker are invalidated when
* the picker is dismissed, unless reference to it is held. This API allows
* the application to signal when it's finished with the video so that the
* reference can be cleaned up.
* It is safe to call this method for urlsthat aren't video URLs;
* it will be a no-op.
*/
removePendingVideo: function (url: string): void {
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
NativeImagePickerIOS.removePendingVideo(url);
},
/**
* WARNING: In most cases, removePendingVideo should be used instead because
* clearAllPendingVideos could clear out pending videos made by other callers.
*/
clearAllPendingVideos: function (): void {
invariant(NativeImagePickerIOS, 'ImagePickerIOS is not available');
NativeImagePickerIOS.clearAllPendingVideos();
},
};
module.exports = ImagePickerIOS;
-39
View File
@@ -1,39 +0,0 @@
/**
* 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.
*
* @flow strict
* @format
*/
import type {TurboModule} from '../TurboModule/RCTExport';
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
export interface Spec extends TurboModule {
+getConstants: () => {||};
+canRecordVideos: (callback: (result: boolean) => void) => void;
+canUseCamera: (callback: (result: boolean) => void) => void;
+openCameraDialog: (
config: {|
unmirrorFrontFacingCamera: boolean,
videoMode: boolean,
|},
successCallback: (imageURL: string, height: number, width: number) => void,
cancelCallback: () => void,
) => void;
+openSelectDialog: (
config: {|
showImages: boolean,
showVideos: boolean,
|},
successCallback: (imageURL: string, height: number, width: number) => void,
cancelCallback: () => void,
) => void;
+clearAllPendingVideos: () => void;
+removePendingVideo: (url: string) => void;
}
export default (TurboModuleRegistry.get<Spec>('ImagePickerIOS'): ?Spec);
@@ -1,124 +0,0 @@
/**
* 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
* @flow strict
*/
'use strict';
export type Timestamp = number;
export type PerformanceEntryType = 'event';
export class PerformanceEntry {
name: string;
entryType: PerformanceEntryType;
startTime: Timestamp;
duration: number;
// For "event" entries only:
processingStart: ?Timestamp;
processingEnd: ?Timestamp;
interactionId: ?number;
// $FlowIgnore: Flow(unclear-type)
toJSON(): Object {
return {
name: this.name,
entryType: this.entryType,
startTime: this.startTime,
duration: this.duration,
};
}
}
export type PerformanceEntryList = $ReadOnlyArray<PerformanceEntry>;
export class PerformanceObserverEntryList {
_entries: PerformanceEntryList;
constructor(entries: PerformanceEntryList) {
this._entries = entries;
}
getEntries(): PerformanceEntryList {
return this._entries;
}
getEntriesByType(type: PerformanceEntryType): PerformanceEntryList {
return this._entries.filter(entry => entry.entryType === type);
}
getEntriesByName(
name: string,
type?: PerformanceEntryType,
): PerformanceEntryList {
if (type === undefined) {
return this._entries.filter(entry => entry.name === name);
} else {
return this._entries.filter(
entry => entry.name === name && entry.entryType === type,
);
}
}
}
export type PerformanceObserverCallback = (
list: PerformanceObserverEntryList,
observer: PerformanceObserver,
) => void;
export type PerformanceObserverInit =
| {
entryTypes: PerformanceEntryType[],
buffered?: boolean,
}
| {
type: PerformanceEntryType,
buffered?: boolean,
};
/**
* Implementation of the PerformanceObserver interface for RN,
* corresponding to the standard in https://www.w3.org/TR/performance-timeline/
*
* @example
* const observer = new PerformanceObserver((list, _observer) => {
* const entries = list.getEntries();
* entries.forEach(entry => {
* reportEvent({
* eventName: entry.name,
* startTime: entry.startTime,
* endTime: entry.startTime + entry.duration,
* processingStart: entry.processingStart,
* processingEnd: entry.processingEnd,
* interactionId: entry.interactionId,
* });
* });
* });
* observer.observe({ type: "event" });
*/
export default class PerformanceObserver {
_callback: PerformanceObserverCallback;
constructor(callback: PerformanceObserverCallback) {
this._callback = callback;
}
observe(options: PerformanceObserverInit) {
console.log('PerformanceObserver: started observing');
}
disconnect(): void {
console.log('PerformanceObserver: stopped observing');
}
takeRecords(): PerformanceEntryList {
return [];
}
static supportedEntryTypes: PerformanceEntryType[] = ['event'];
}
@@ -36,6 +36,7 @@ RCT_REMAP_SHADOW_PROPERTY(fontWeight, textAttributes.fontWeight, NSString)
RCT_REMAP_SHADOW_PROPERTY(fontStyle, textAttributes.fontStyle, NSString)
RCT_REMAP_SHADOW_PROPERTY(fontVariant, textAttributes.fontVariant, NSArray)
RCT_REMAP_SHADOW_PROPERTY(allowFontScaling, textAttributes.allowFontScaling, BOOL)
RCT_REMAP_SHADOW_PROPERTY(dynamicTypeRamp, textAttributes.dynamicTypeRamp, RCTDynamicTypeRamp)
RCT_REMAP_SHADOW_PROPERTY(maxFontSizeMultiplier, textAttributes.maxFontSizeMultiplier, CGFloat)
RCT_REMAP_SHADOW_PROPERTY(letterSpacing, textAttributes.letterSpacing, CGFloat)
// Paragraph Styles
+2
View File
@@ -7,6 +7,7 @@
#import <UIKit/UIKit.h>
#import <React/RCTDynamicTypeRamp.h>
#import <React/RCTTextDecorationLineType.h>
#import "RCTTextTransform.h"
@@ -36,6 +37,7 @@ extern NSString *const RCTTextAttributesTagAttributeName;
@property (nonatomic, copy, nullable) NSString *fontStyle;
@property (nonatomic, copy, nullable) NSArray<NSString *> *fontVariant;
@property (nonatomic, assign) BOOL allowFontScaling;
@property (nonatomic, assign) RCTDynamicTypeRamp dynamicTypeRamp;
@property (nonatomic, assign) CGFloat letterSpacing;
// Paragraph Styles
@property (nonatomic, assign) CGFloat lineHeight;
+9 -1
View File
@@ -59,6 +59,8 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib
_fontStyle = textAttributes->_fontStyle ?: _fontStyle;
_fontVariant = textAttributes->_fontVariant ?: _fontVariant;
_allowFontScaling = textAttributes->_allowFontScaling || _allowFontScaling; // *
_dynamicTypeRamp = textAttributes->_dynamicTypeRamp != RCTDynamicTypeRampUndefined ? textAttributes->_dynamicTypeRamp
: _dynamicTypeRamp;
_letterSpacing = !isnan(textAttributes->_letterSpacing) ? textAttributes->_letterSpacing : _letterSpacing;
// Paragraph Styles
@@ -230,6 +232,12 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib
if (fontScalingEnabled) {
CGFloat fontSizeMultiplier = !isnan(_fontSizeMultiplier) ? _fontSizeMultiplier : 1.0;
if (_dynamicTypeRamp != RCTDynamicTypeRampUndefined) {
UIFontMetrics *fontMetrics = RCTUIFontMetricsForDynamicTypeRamp(_dynamicTypeRamp);
// Using a specific font size reduces rounding errors from -scaledValueForValue:
CGFloat requestedSize = isnan(_fontSize) ? RCTBaseSizeForDynamicTypeRamp(_dynamicTypeRamp) : _fontSize;
fontSizeMultiplier = [fontMetrics scaledValueForValue:requestedSize] / requestedSize;
}
CGFloat maxFontSizeMultiplier = !isnan(_maxFontSizeMultiplier) ? _maxFontSizeMultiplier : 0.0;
return maxFontSizeMultiplier >= 1.0 ? fminf(maxFontSizeMultiplier, fontSizeMultiplier) : fontSizeMultiplier;
} else {
@@ -324,7 +332,7 @@ static NSString *capitalizeText(NSString *text)
RCTTextAttributesCompareFloats(_fontSizeMultiplier) && RCTTextAttributesCompareFloats(_maxFontSizeMultiplier) &&
RCTTextAttributesCompareStrings(_fontWeight) && RCTTextAttributesCompareObjects(_fontStyle) &&
RCTTextAttributesCompareObjects(_fontVariant) && RCTTextAttributesCompareOthers(_allowFontScaling) &&
RCTTextAttributesCompareFloats(_letterSpacing) &&
RCTTextAttributesCompareOthers(_dynamicTypeRamp) && RCTTextAttributesCompareFloats(_letterSpacing) &&
// Paragraph Styles
RCTTextAttributesCompareFloats(_lineHeight) && RCTTextAttributesCompareFloats(_alignment) &&
RCTTextAttributesCompareOthers(_baseWritingDirection) && RCTTextAttributesCompareOthers(_lineBreakStrategy) &&
+17
View File
@@ -26,6 +26,23 @@ export interface TextPropsIOS {
*/
adjustsFontSizeToFit?: boolean | undefined;
/**
* The Dynamic Text scale ramp to apply to this element on iOS.
*/
dynamicTypeRamp?:
| 'caption2'
| 'caption1'
| 'footnote'
| 'subheadline'
| 'callout'
| 'body'
| 'headline'
| 'title3'
| 'title2'
| 'title1'
| 'largeTitle'
| undefined;
/**
* Specifies smallest possible scale a font can reach when adjustsFontSizeToFit is enabled. (values 0.01-1.0).
*/
+37
View File
@@ -0,0 +1,37 @@
/*
* 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>
#import <React/RCTConvert.h>
typedef NS_ENUM(NSInteger, RCTDynamicTypeRamp) {
RCTDynamicTypeRampUndefined,
RCTDynamicTypeRampCaption2,
RCTDynamicTypeRampCaption1,
RCTDynamicTypeRampFootnote,
RCTDynamicTypeRampSubheadline,
RCTDynamicTypeRampCallout,
RCTDynamicTypeRampBody,
RCTDynamicTypeRampHeadline,
RCTDynamicTypeRampTitle3,
RCTDynamicTypeRampTitle2,
RCTDynamicTypeRampTitle1,
RCTDynamicTypeRampLargeTitle
};
@interface RCTConvert (DynamicTypeRamp)
+ (RCTDynamicTypeRamp)RCTDynamicTypeRamp:(nullable id)json;
@end
/// Generates a `UIFontMetrics` instance representing a particular Dynamic Type ramp.
UIFontMetrics *_Nonnull RCTUIFontMetricsForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp);
/// The "reference" size for a particular font scale ramp, equal to a text element's size under default text size
/// settings.
CGFloat RCTBaseSizeForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp);
+82
View File
@@ -0,0 +1,82 @@
/*
* 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 <React/RCTDynamicTypeRamp.h>
@implementation RCTConvert (DynamicTypeRamp)
RCT_ENUM_CONVERTER(
RCTDynamicTypeRamp,
(@{
@"caption2" : @(RCTDynamicTypeRampCaption2),
@"caption1" : @(RCTDynamicTypeRampCaption1),
@"footnote" : @(RCTDynamicTypeRampFootnote),
@"subheadline" : @(RCTDynamicTypeRampSubheadline),
@"callout" : @(RCTDynamicTypeRampCallout),
@"body" : @(RCTDynamicTypeRampBody),
@"headline" : @(RCTDynamicTypeRampHeadline),
@"title3" : @(RCTDynamicTypeRampTitle3),
@"title2" : @(RCTDynamicTypeRampTitle2),
@"title1" : @(RCTDynamicTypeRampTitle1),
@"largeTitle" : @(RCTDynamicTypeRampLargeTitle),
}),
RCTDynamicTypeRampUndefined,
integerValue)
@end
UIFontMetrics *RCTUIFontMetricsForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp)
{
static NSDictionary<NSNumber *, UIFontTextStyle> *mapping;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mapping = @{
@(RCTDynamicTypeRampCaption2) : UIFontTextStyleCaption2,
@(RCTDynamicTypeRampCaption1) : UIFontTextStyleCaption1,
@(RCTDynamicTypeRampFootnote) : UIFontTextStyleFootnote,
@(RCTDynamicTypeRampSubheadline) : UIFontTextStyleSubheadline,
@(RCTDynamicTypeRampCallout) : UIFontTextStyleCallout,
@(RCTDynamicTypeRampBody) : UIFontTextStyleBody,
@(RCTDynamicTypeRampHeadline) : UIFontTextStyleHeadline,
@(RCTDynamicTypeRampTitle3) : UIFontTextStyleTitle3,
@(RCTDynamicTypeRampTitle2) : UIFontTextStyleTitle2,
@(RCTDynamicTypeRampTitle1) : UIFontTextStyleTitle1,
@(RCTDynamicTypeRampLargeTitle) : UIFontTextStyleLargeTitle,
};
});
id textStyle =
mapping[@(dynamicTypeRamp)] ?: UIFontTextStyleBody; // Default to body if we don't recognize the specified ramp
return [UIFontMetrics metricsForTextStyle:textStyle];
}
CGFloat RCTBaseSizeForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp)
{
static NSDictionary<NSNumber *, NSNumber *> *mapping;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Values taken from
// https://developer.apple.com/design/human-interface-guidelines/foundations/typography/#specifications
mapping = @{
@(RCTDynamicTypeRampCaption2) : @11,
@(RCTDynamicTypeRampCaption1) : @12,
@(RCTDynamicTypeRampFootnote) : @13,
@(RCTDynamicTypeRampSubheadline) : @15,
@(RCTDynamicTypeRampCallout) : @16,
@(RCTDynamicTypeRampBody) : @17,
@(RCTDynamicTypeRampHeadline) : @17,
@(RCTDynamicTypeRampTitle3) : @20,
@(RCTDynamicTypeRampTitle2) : @22,
@(RCTDynamicTypeRampTitle1) : @28,
@(RCTDynamicTypeRampLargeTitle) : @34,
};
});
NSNumber *baseSize =
mapping[@(dynamicTypeRamp)] ?: @17; // Default to body size if we don't recognize the specified ramp
return CGFLOAT_IS_DOUBLE ? [baseSize doubleValue] : [baseSize floatValue];
}
+1
View File
@@ -34,6 +34,7 @@ const textViewConfig = {
numberOfLines: true,
ellipsizeMode: true,
allowFontScaling: true,
dynamicTypeRamp: true,
maxFontSizeMultiplier: true,
disabled: true,
selectable: true,
+17
View File
@@ -229,6 +229,23 @@ export type TextProps = $ReadOnly<{|
*/
adjustsFontSizeToFit?: ?boolean,
/**
* The Dynamic Text scale ramp to apply to this element on iOS.
*/
dynamicTypeRamp?: ?(
| 'caption2'
| 'caption1'
| 'footnote'
| 'subheadline'
| 'callout'
| 'body'
| 'headline'
| 'title3'
| 'title2'
| 'title1'
| 'largeTitle'
),
/**
* Smallest possible scale a font can reach.
*
@@ -0,0 +1,42 @@
/*
* 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.
*/
#include "NativePerformanceObserver.h"
#include <glog/logging.h>
namespace facebook::react {
NativePerformanceObserver::NativePerformanceObserver(
std::shared_ptr<CallInvoker> jsInvoker)
: NativePerformanceObserverCxxSpec(std::move(jsInvoker)) {}
void NativePerformanceObserver::startReporting(
jsi::Runtime &rt,
std::string entryType) {
LOG(INFO) << "Started reporting perf entry type: " << entryType;
}
void NativePerformanceObserver::stopReporting(
jsi::Runtime &rt,
std::string entryType) {
LOG(INFO) << "Stopped reporting perf entry type: " << entryType;
}
std::vector<RawPerformanceEntry> NativePerformanceObserver::getPendingEntries(
jsi::Runtime &rt) {
return std::vector<RawPerformanceEntry>{};
}
void NativePerformanceObserver::setOnPerformanceEntryCallback(
jsi::Runtime &rt,
std::optional<AsyncCallback<>> callback) {
callback_ = callback;
LOG(INFO) << "setOnPerformanceEntryCallback: "
<< (callback ? "non-empty" : "empty");
}
} // namespace facebook::react
@@ -0,0 +1,64 @@
/*
* 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.
*/
#pragma once
#include <FBReactNativeSpec/FBReactNativeSpecJSI.h>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <vector>
namespace facebook::react {
#pragma mark - Structs
using RawPerformanceEntry = NativePerformanceObserverCxxBaseRawPerformanceEntry<
std::string,
int32_t,
double,
double,
// For "event" entries only:
std::optional<double>,
std::optional<double>,
std::optional<double>>;
template <>
struct Bridging<RawPerformanceEntry>
: NativePerformanceObserverCxxBaseRawPerformanceEntryBridging<
std::string,
int32_t,
double,
double,
std::optional<double>,
std::optional<double>,
std::optional<double>> {};
#pragma mark - implementation
class NativePerformanceObserver
: public NativePerformanceObserverCxxSpec<NativePerformanceObserver>,
std::enable_shared_from_this<NativePerformanceObserver> {
public:
NativePerformanceObserver(std::shared_ptr<CallInvoker> jsInvoker);
void startReporting(jsi::Runtime &rt, std::string entryType);
void stopReporting(jsi::Runtime &rt, std::string entryType);
std::vector<RawPerformanceEntry> getPendingEntries(jsi::Runtime &rt);
void setOnPerformanceEntryCallback(
jsi::Runtime &rt,
std::optional<AsyncCallback<>> callback);
private:
std::optional<AsyncCallback<>> callback_;
};
} // namespace facebook::react
@@ -0,0 +1,41 @@
/**
* 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.
*
* @flow strict
* @format
*/
import type {TurboModule} from '../TurboModule/RCTExport';
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
export const RawPerformanceEntryTypeValues = {
UNDEFINED: 0,
};
export type RawPerformanceEntryType = number;
export type RawPerformanceEntry = {|
name: string,
entryType: RawPerformanceEntryType,
startTime: number,
duration: number,
// For "event" entries only:
processingStart?: number,
processingEnd?: number,
interactionId?: number,
|};
export interface Spec extends TurboModule {
+startReporting: (entryType: string) => void;
+stopReporting: (entryType: string) => void;
+getPendingEntries: () => $ReadOnlyArray<RawPerformanceEntry>;
+setOnPerformanceEntryCallback: (callback?: () => void) => void;
}
export default (TurboModuleRegistry.get<Spec>(
'NativePerformanceObserverCxx',
): ?Spec);
@@ -0,0 +1,223 @@
/**
* 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
* @flow strict
*/
import type {
RawPerformanceEntry,
RawPerformanceEntryType,
} from './NativePerformanceObserver';
import warnOnce from '../Utilities/warnOnce';
import NativePerformanceObserver from './NativePerformanceObserver';
export type HighResTimeStamp = number;
// TODO: Extend once new types (such as event) are supported.
// TODO: Get rid of the "undefined" once there is at least one type supported.
export type PerformanceEntryType = 'undefined';
export class PerformanceEntry {
name: string;
entryType: PerformanceEntryType;
startTime: HighResTimeStamp;
duration: number;
constructor(init: {
name: string,
entryType: PerformanceEntryType,
startTime: HighResTimeStamp,
duration: number,
}) {
this.name = init.name;
this.entryType = init.entryType;
this.startTime = init.startTime;
this.duration = init.duration;
}
// $FlowIgnore: Flow(unclear-type)
toJSON(): Object {
return {
name: this.name,
entryType: this.entryType,
startTime: this.startTime,
duration: this.duration,
};
}
}
function rawToPerformanceEntryType(
type: RawPerformanceEntryType,
): PerformanceEntryType {
return 'undefined';
}
function rawToPerformanceEntry(entry: RawPerformanceEntry): PerformanceEntry {
return new PerformanceEntry({
name: entry.name,
entryType: rawToPerformanceEntryType(entry.entryType),
startTime: entry.startTime,
duration: entry.duration,
});
}
export type PerformanceEntryList = $ReadOnlyArray<PerformanceEntry>;
export class PerformanceObserverEntryList {
_entries: PerformanceEntryList;
constructor(entries: PerformanceEntryList) {
this._entries = entries;
}
getEntries(): PerformanceEntryList {
return this._entries;
}
getEntriesByType(type: PerformanceEntryType): PerformanceEntryList {
return this._entries.filter(entry => entry.entryType === type);
}
getEntriesByName(
name: string,
type?: PerformanceEntryType,
): PerformanceEntryList {
if (type === undefined) {
return this._entries.filter(entry => entry.name === name);
} else {
return this._entries.filter(
entry => entry.name === name && entry.entryType === type,
);
}
}
}
export type PerformanceObserverCallback = (
list: PerformanceObserverEntryList,
observer: PerformanceObserver,
) => void;
export type PerformanceObserverInit =
| {
entryTypes: Array<PerformanceEntryType>,
}
| {
type: PerformanceEntryType,
};
let _observedEntryTypeRefCount: Map<PerformanceEntryType, number> = new Map();
let _observers: Set<PerformanceObserver> = new Set();
let _onPerformanceEntryCallbackIsSet: boolean = false;
function warnNoNativePerformanceObserver() {
warnOnce(
'missing-native-performance-observer',
'Missing native implementation of PerformanceObserver',
);
}
/**
* Implementation of the PerformanceObserver interface for RN,
* corresponding to the standard in https://www.w3.org/TR/performance-timeline/
*
* @example
* const observer = new PerformanceObserver((list, _observer) => {
* const entries = list.getEntries();
* entries.forEach(entry => {
* reportEvent({
* eventName: entry.name,
* startTime: entry.startTime,
* endTime: entry.startTime + entry.duration,
* processingStart: entry.processingStart,
* processingEnd: entry.processingEnd,
* interactionId: entry.interactionId,
* });
* });
* });
* observer.observe({ type: "event" });
*/
export default class PerformanceObserver {
_callback: PerformanceObserverCallback;
_entryTypes: $ReadOnlySet<PerformanceEntryType>;
constructor(callback: PerformanceObserverCallback) {
this._callback = callback;
}
observe(options: PerformanceObserverInit) {
if (!NativePerformanceObserver) {
warnNoNativePerformanceObserver();
return;
}
if (!_onPerformanceEntryCallbackIsSet) {
NativePerformanceObserver.setOnPerformanceEntryCallback(
onPerformanceEntry,
);
_onPerformanceEntryCallbackIsSet = true;
}
if (options.entryTypes) {
this._entryTypes = new Set(options.entryTypes);
} else {
this._entryTypes = new Set([options.type]);
}
this._entryTypes.forEach(type => {
if (!_observedEntryTypeRefCount.has(type)) {
NativePerformanceObserver.startReporting(type);
}
_observedEntryTypeRefCount.set(
type,
(_observedEntryTypeRefCount.get(type) ?? 0) + 1,
);
});
_observers.add(this);
}
disconnect(): void {
if (!NativePerformanceObserver) {
warnNoNativePerformanceObserver();
return;
}
this._entryTypes.forEach(type => {
const entryTypeRefCount = _observedEntryTypeRefCount.get(type) ?? 0;
if (entryTypeRefCount === 1) {
_observedEntryTypeRefCount.delete(type);
NativePerformanceObserver.stopReporting(type);
} else if (entryTypeRefCount !== 0) {
_observedEntryTypeRefCount.set(type, entryTypeRefCount - 1);
}
});
_observers.delete(this);
if (_observers.size === 0) {
NativePerformanceObserver.setOnPerformanceEntryCallback(undefined);
_onPerformanceEntryCallbackIsSet = false;
}
}
static supportedEntryTypes: $ReadOnlyArray<PerformanceEntryType> =
// TODO: add types once they are fully supported
Object.freeze([]);
}
// This is a callback that gets scheduled and periodically called from the native side
function onPerformanceEntry() {
if (!NativePerformanceObserver) {
return;
}
const rawEntries = NativePerformanceObserver.getPendingEntries();
const entries = rawEntries.map(rawToPerformanceEntry);
_observers.forEach(observer => {
const entriesForObserver: PerformanceEntryList = entries.filter(entry =>
observer._entryTypes.has(entry.entryType),
);
observer._callback(
new PerformanceObserverEntryList(entriesForObserver),
observer,
);
});
}
+3 -3
View File
@@ -21,10 +21,10 @@ NSDictionary* RCTGetReactNativeVersion(void)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^(void){
__rnVersion = @{
RCTVersionMajor: @(1000),
RCTVersionMinor: @(0),
RCTVersionMajor: @(0),
RCTVersionMinor: @(71),
RCTVersionPatch: @(0),
RCTVersionPrerelease: [NSNull null],
RCTVersionPrerelease: @"rc.2",
};
});
return __rnVersion;
+1 -1
View File
@@ -36,7 +36,6 @@ Class RCTCoreModulesClassProvider(const char *name) {
{"PerfMonitor", RCTPerfMonitorCls},
{"DevMenu", RCTDevMenuCls},
{"DevSettings", RCTDevSettingsCls},
{"BlobModule", RCTBlobManagerCls},
{"RedBox", RCTRedBoxCls},
{"LogBox", RCTLogBoxCls},
{"WebSocketExecutor", RCTWebSocketExecutorCls},
@@ -44,6 +43,7 @@ Class RCTCoreModulesClassProvider(const char *name) {
{"DevLoadingView", RCTDevLoadingViewCls},
{"DevSplitBundleLoader", RCTDevSplitBundleLoaderCls},
{"EventDispatcher", RCTEventDispatcherCls},
{"BlobModule", RCTBlobManagerCls},
};
auto p = sCoreModuleClassMap->find(name);
+7 -5
View File
@@ -363,8 +363,8 @@ task installArchives {
}
android {
buildToolsVersion = "31.0.0"
compileSdkVersion 31
buildToolsVersion = "33.0.0"
compileSdkVersion 33
// Used to override the NDK path/version on internal CI or by allowing
// users to customize the NDK path/version from their root project (e.g. for M1 support)
@@ -377,7 +377,7 @@ android {
defaultConfig {
minSdkVersion(21)
targetSdkVersion(31)
targetSdkVersion(33)
versionCode(1)
versionName("1.0")
@@ -616,11 +616,13 @@ apply plugin: "org.jetbrains.kotlin.android"
apply from: "./publish.gradle"
// We need to override the artifact ID as this project is called `ReactAndroid` but
// the maven coordinates are on `react-native`.
// the maven coordinates are on `react-android`.
// Please note that the original coordinates, `react-native`, have been voided
// as they caused https://github.com/facebook/react-native/issues/35210
publishing {
publications {
getByName("release") {
artifactId 'react-native'
artifactId 'react-android'
}
}
}
@@ -106,7 +106,7 @@ if(EXISTS ${PROJECT_BUILD_DIR}/generated/rncli/src/main/jni/Android-rncli.cmake)
include(${PROJECT_BUILD_DIR}/generated/rncli/src/main/jni/Android-rncli.cmake)
target_link_libraries(${CMAKE_PROJECT_NAME} ${AUTOLINKED_LIBRARIES})
foreach(autolinked_library ${AUTOLINKED_LIBRARIES})
target_link_libraries(autolinked_library common_flags)
target_link_libraries(${autolinked_library} common_flags)
endforeach()
endif()
@@ -48,7 +48,14 @@ void registerComponents(
rncli_registerProviders(registry);
}
std::shared_ptr<TurboModule> provideModules(
std::shared_ptr<TurboModule> cxxModuleProvider(
const std::string &name,
const std::shared_ptr<CallInvoker> &jsInvoker) {
// Not implemented yet: provide pure-C++ NativeModules here.
return nullptr;
}
std::shared_ptr<TurboModule> javaModuleProvider(
const std::string &name,
const JavaTurboModule::InitParams &params) {
// Here you can provide your own module provider for TurboModules coming from
@@ -70,8 +77,10 @@ std::shared_ptr<TurboModule> provideModules(
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
return facebook::jni::initialize(vm, [] {
facebook::react::DefaultTurboModuleManagerDelegate::
moduleProvidersFromEntryPoint = &facebook::react::provideModules;
facebook::react::DefaultTurboModuleManagerDelegate::cxxModuleProvider =
&facebook::react::cxxModuleProvider;
facebook::react::DefaultTurboModuleManagerDelegate::javaModuleProvider =
&facebook::react::javaModuleProvider;
facebook::react::DefaultComponentsRegistry::
registerComponentDescriptorsFromEntryPoint =
&facebook::react::registerComponents;
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION_NAME=1000.0.0
VERSION_NAME=0.71.0-rc.2
GROUP=com.facebook.react
# JVM Versions
+13
View File
@@ -234,4 +234,17 @@ afterEvaluate {
prepareHeadersForPrefab.dependsOn(buildHermes)
}
/* Publishing Configuration */
apply from: "../publish.gradle"
// We need to override the artifact ID as this project is called `hermes-engine` but
// the maven coordinates are on `hermes-android`.
// Please note that the original coordinates, `hermes-engine`, have been voided
// as they caused https://github.com/facebook/react-native/issues/35210
publishing {
publications {
getByName("release") {
artifactId 'hermes-android'
}
}
}
@@ -15,8 +15,8 @@ import java.util.Map;
public class ReactNativeVersion {
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
"major", 1000,
"minor", 0,
"major", 0,
"minor", 71,
"patch", 0,
"prerelease", null);
"prerelease", "rc.2");
}
@@ -120,7 +120,9 @@ public class ReactModalHostView extends ViewGroup
@Override
public int getChildCount() {
return mHostView.getChildCount();
// This method may be called by the parent constructor
// before mHostView is initialized.
return mHostView == null ? 0 : mHostView.getChildCount();
}
@Override
@@ -12,10 +12,15 @@
namespace facebook {
namespace react {
std::function<std::shared_ptr<TurboModule>(
const std::string &,
const std::shared_ptr<CallInvoker> &)>
DefaultTurboModuleManagerDelegate::cxxModuleProvider{nullptr};
std::function<std::shared_ptr<TurboModule>(
const std::string &,
const JavaTurboModule::InitParams &)>
DefaultTurboModuleManagerDelegate::moduleProvidersFromEntryPoint{nullptr};
DefaultTurboModuleManagerDelegate::javaModuleProvider{nullptr};
jni::local_ref<DefaultTurboModuleManagerDelegate::jhybriddata>
DefaultTurboModuleManagerDelegate::initHybrid(jni::alias_ref<jhybridobject>) {
@@ -32,17 +37,21 @@ void DefaultTurboModuleManagerDelegate::registerNatives() {
std::shared_ptr<TurboModule> DefaultTurboModuleManagerDelegate::getTurboModule(
const std::string &name,
const std::shared_ptr<CallInvoker> &jsInvoker) {
// Not implemented yet: provide pure-C++ NativeModules here.
auto moduleProvider = DefaultTurboModuleManagerDelegate::cxxModuleProvider;
if (moduleProvider) {
return moduleProvider(name, jsInvoker);
}
return nullptr;
}
std::shared_ptr<TurboModule> DefaultTurboModuleManagerDelegate::getTurboModule(
const std::string &name,
const JavaTurboModule::InitParams &params) {
auto resolvedModule = (DefaultTurboModuleManagerDelegate::
moduleProvidersFromEntryPoint)(name, params);
if (resolvedModule != nullptr) {
return resolvedModule;
auto moduleProvider = DefaultTurboModuleManagerDelegate::javaModuleProvider;
if (moduleProvider) {
if (auto resolvedModule = moduleProvider(name, params)) {
return resolvedModule;
}
}
return rncore_ModuleProvider(name, params);
}
@@ -27,10 +27,15 @@ class DefaultTurboModuleManagerDelegate : public jni::HybridClass<
static void registerNatives();
static std::function<std::shared_ptr<TurboModule>(
const std::string &,
const std::shared_ptr<CallInvoker> &)>
cxxModuleProvider;
static std::function<std::shared_ptr<TurboModule>(
const std::string &,
const JavaTurboModule::InitParams &)>
moduleProvidersFromEntryPoint;
javaModuleProvider;
std::shared_ptr<TurboModule> getTurboModule(
const std::string &name,
-43
View File
@@ -1,43 +0,0 @@
# 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 -Wno-gnu-zero-variadic-macro-arguments'
folly_version = '2021.07.22.00'
Pod::Spec.new do |s|
s.name = "React-bridging"
s.version = version
s.summary = "-" # TODO
s.homepage = "https://reactnative.dev/"
s.license = package["license"]
s.author = "Facebook, Inc. and its affiliates"
s.platforms = { :ios => "12.4" }
s.source = source
s.source_files = "react/bridging/**/*.{cpp,h}"
s.exclude_files = "react/bridging/tests"
s.header_dir = "react/bridging"
s.header_mappings_dir = "."
s.compiler_flags = folly_compiler_flags
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/RCT-Folly\"",
"USE_HEADERMAP" => "YES",
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
"GCC_WARN_PEDANTIC" => "YES" }
s.dependency "RCT-Folly", folly_version
s.dependency "React-jsi", version
end
+9 -2
View File
@@ -32,7 +32,7 @@ Pod::Spec.new do |s|
s.source = source
s.header_dir = "ReactCommon" # Use global header_dir for all subspecs for use_frameworks! compatibility
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\" \"$(PODS_ROOT)/Headers/Private/React-Core\" \"$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers\"",
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/Headers/Private/React-Core\"",
"USE_HEADERMAP" => "YES",
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
"GCC_WARN_PEDANTIC" => "YES" }
@@ -40,7 +40,6 @@ Pod::Spec.new do |s|
# TODO (T48588859): Restructure this target to align with dir structure: "react/nativemodule/..."
# Note: Update this only when ready to minimize breaking changes.
s.subspec "turbomodule" do |ss|
ss.dependency "React-bridging", version
ss.dependency "React-callinvoker", version
ss.dependency "React-perflogger", version
ss.dependency "React-Core", version
@@ -51,6 +50,14 @@ Pod::Spec.new do |s|
ss.dependency "DoubleConversion"
ss.dependency "glog"
ss.subspec "bridging" do |sss|
sss.dependency "React-jsi", version
sss.source_files = "react/bridging/**/*.{cpp,h}"
sss.exclude_files = "react/bridging/tests"
sss.header_dir = "react/bridging"
sss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/RCT-Folly\"" }
end
ss.subspec "core" do |sss|
sss.source_files = "react/nativemodule/core/ReactCommon/**/*.{cpp,h}",
"react/nativemodule/core/platform/ios/**/*.{mm,cpp,h}"
+3 -3
View File
@@ -15,10 +15,10 @@
namespace facebook::react {
constexpr struct {
int32_t Major = 1000;
int32_t Minor = 0;
int32_t Major = 0;
int32_t Minor = 71;
int32_t Patch = 0;
std::string_view Prerelease = "";
std::string_view Prerelease = "rc.2";
} ReactNativeVersion;
} // namespace facebook::react
@@ -46,6 +46,9 @@ void TextAttributes::apply(TextAttributes textAttributes) {
allowFontScaling = textAttributes.allowFontScaling.has_value()
? textAttributes.allowFontScaling
: allowFontScaling;
dynamicTypeRamp = textAttributes.dynamicTypeRamp.has_value()
? textAttributes.dynamicTypeRamp
: dynamicTypeRamp;
letterSpacing = !std::isnan(textAttributes.letterSpacing)
? textAttributes.letterSpacing
: letterSpacing;
@@ -111,6 +114,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const {
fontStyle,
fontVariant,
allowFontScaling,
dynamicTypeRamp,
alignment,
baseWritingDirection,
lineBreakStrategy,
@@ -131,6 +135,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const {
rhs.fontStyle,
rhs.fontVariant,
rhs.allowFontScaling,
rhs.dynamicTypeRamp,
rhs.alignment,
rhs.baseWritingDirection,
rhs.lineBreakStrategy,
@@ -186,6 +191,7 @@ SharedDebugStringConvertibleList TextAttributes::getDebugProps() const {
debugStringConvertibleItem("fontStyle", fontStyle),
debugStringConvertibleItem("fontVariant", fontVariant),
debugStringConvertibleItem("allowFontScaling", allowFontScaling),
debugStringConvertibleItem("dynamicTypeRamp", dynamicTypeRamp),
debugStringConvertibleItem("letterSpacing", letterSpacing),
// Paragraph Styles
@@ -50,6 +50,7 @@ class TextAttributes : public DebugStringConvertible {
std::optional<FontStyle> fontStyle{};
std::optional<FontVariant> fontVariant{};
std::optional<bool> allowFontScaling{};
std::optional<DynamicTypeRamp> dynamicTypeRamp{};
Float letterSpacing{std::numeric_limits<Float>::quiet_NaN()};
std::optional<TextTransform> textTransform{};
@@ -34,6 +34,84 @@
namespace facebook {
namespace react {
inline std::string toString(const DynamicTypeRamp &dynamicTypeRamp) {
switch (dynamicTypeRamp) {
case DynamicTypeRamp::Caption2:
return "caption2";
case DynamicTypeRamp::Caption1:
return "caption1";
case DynamicTypeRamp::Footnote:
return "footnote";
case DynamicTypeRamp::Subheadline:
return "subheadline";
case DynamicTypeRamp::Callout:
return "callout";
case DynamicTypeRamp::Body:
return "body";
case DynamicTypeRamp::Headline:
return "headline";
case DynamicTypeRamp::Title3:
return "title3";
case DynamicTypeRamp::Title2:
return "title2";
case DynamicTypeRamp::Title1:
return "title1";
case DynamicTypeRamp::LargeTitle:
return "largeTitle";
}
LOG(ERROR) << "Unsupported DynamicTypeRamp value";
react_native_assert(false);
// Sane default in case of parsing errors
return "body";
}
inline void fromRawValue(
const PropsParserContext &context,
const RawValue &value,
DynamicTypeRamp &result) {
react_native_assert(value.hasType<std::string>());
if (value.hasType<std::string>()) {
auto string = (std::string)value;
if (string == "caption2") {
result = DynamicTypeRamp::Caption2;
} else if (string == "caption1") {
result = DynamicTypeRamp::Caption1;
} else if (string == "footnote") {
result = DynamicTypeRamp::Footnote;
} else if (string == "subheadline") {
result = DynamicTypeRamp::Subheadline;
} else if (string == "callout") {
result = DynamicTypeRamp::Callout;
} else if (string == "body") {
result = DynamicTypeRamp::Body;
} else if (string == "headline") {
result = DynamicTypeRamp::Headline;
} else if (string == "title3") {
result = DynamicTypeRamp::Title3;
} else if (string == "title2") {
result = DynamicTypeRamp::Title2;
} else if (string == "title1") {
result = DynamicTypeRamp::Title1;
} else if (string == "largeTitle") {
result = DynamicTypeRamp::LargeTitle;
} else {
// sane default
LOG(ERROR) << "Unsupported DynamicTypeRamp value: " << string;
react_native_assert(false);
result = DynamicTypeRamp::Body;
}
return;
}
LOG(ERROR) << "Unsupported DynamicTypeRamp type";
react_native_assert(false);
// Sane default in case of parsing errors
result = DynamicTypeRamp::Body;
}
inline std::string toString(const EllipsizeMode &ellipsisMode) {
switch (ellipsisMode) {
case EllipsizeMode::Clip:
@@ -46,6 +46,20 @@ enum class FontVariant : int {
ProportionalNums = 1 << 5
};
enum class DynamicTypeRamp {
Caption2,
Caption1,
Footnote,
Subheadline,
Callout,
Body,
Headline,
Title3,
Title2,
Title1,
LargeTitle
};
enum class EllipsizeMode {
Clip, // Do not add ellipsize, simply clip.
Head, // Truncate at head of line: "...wxyz".
@@ -190,6 +204,13 @@ struct hash<facebook::react::FontWeight> {
}
};
template <>
struct hash<facebook::react::DynamicTypeRamp> {
size_t operator()(const facebook::react::DynamicTypeRamp &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::EllipsizeMode> {
size_t operator()(const facebook::react::EllipsizeMode &v) const {
@@ -73,6 +73,12 @@ static TextAttributes convertRawProp(
"allowFontScaling",
sourceTextAttributes.allowFontScaling,
defaultTextAttributes.allowFontScaling);
textAttributes.dynamicTypeRamp = convertRawProp(
context,
rawProps,
"dynamicTypeRamp",
sourceTextAttributes.dynamicTypeRamp,
defaultTextAttributes.dynamicTypeRamp);
textAttributes.letterSpacing = convertRawProp(
context,
rawProps,
@@ -94,6 +94,7 @@ inline bool areTextAttributesEquivalentLayoutWise(
lhs.fontStyle,
lhs.fontVariant,
lhs.allowFontScaling,
lhs.dynamicTypeRamp,
lhs.alignment) ==
std::tie(
rhs.fontFamily,
@@ -101,6 +102,7 @@ inline bool areTextAttributesEquivalentLayoutWise(
rhs.fontStyle,
rhs.fontVariant,
rhs.allowFontScaling,
rhs.dynamicTypeRamp,
rhs.alignment) &&
floatEquality(lhs.fontSize, rhs.fontSize) &&
floatEquality(lhs.fontSizeMultiplier, rhs.fontSizeMultiplier) &&
@@ -121,6 +123,7 @@ inline size_t textAttributesHashLayoutWise(
textAttributes.fontStyle,
textAttributes.fontVariant,
textAttributes.allowFontScaling,
textAttributes.dynamicTypeRamp,
textAttributes.letterSpacing,
textAttributes.lineHeight,
textAttributes.alignment);
@@ -55,6 +55,83 @@ inline static UIFontWeight RCTUIFontWeightFromInteger(NSInteger fontWeight)
return weights[(fontWeight + 50) / 100 - 1];
}
inline static UIFontTextStyle RCTUIFontTextStyleForDynamicTypeRamp(const DynamicTypeRamp &dynamicTypeRamp)
{
switch (dynamicTypeRamp) {
case DynamicTypeRamp::Caption2:
return UIFontTextStyleCaption2;
case DynamicTypeRamp::Caption1:
return UIFontTextStyleCaption1;
case DynamicTypeRamp::Footnote:
return UIFontTextStyleFootnote;
case DynamicTypeRamp::Subheadline:
return UIFontTextStyleSubheadline;
case DynamicTypeRamp::Callout:
return UIFontTextStyleCallout;
case DynamicTypeRamp::Body:
return UIFontTextStyleBody;
case DynamicTypeRamp::Headline:
return UIFontTextStyleHeadline;
case DynamicTypeRamp::Title3:
return UIFontTextStyleTitle3;
case DynamicTypeRamp::Title2:
return UIFontTextStyleTitle2;
case DynamicTypeRamp::Title1:
return UIFontTextStyleTitle1;
case DynamicTypeRamp::LargeTitle:
return UIFontTextStyleLargeTitle;
}
}
inline static CGFloat RCTBaseSizeForDynamicTypeRamp(const DynamicTypeRamp &dynamicTypeRamp)
{
// Values taken from
// https://developer.apple.com/design/human-interface-guidelines/foundations/typography/#specifications
switch (dynamicTypeRamp) {
case DynamicTypeRamp::Caption2:
return 11.0;
case DynamicTypeRamp::Caption1:
return 12.0;
case facebook::react::DynamicTypeRamp::Footnote:
return 13.0;
case facebook::react::DynamicTypeRamp::Subheadline:
return 15.0;
case facebook::react::DynamicTypeRamp::Callout:
return 16.0;
case facebook::react::DynamicTypeRamp::Body:
return 17.0;
case facebook::react::DynamicTypeRamp::Headline:
return 17.0;
case facebook::react::DynamicTypeRamp::Title3:
return 20.0;
case facebook::react::DynamicTypeRamp::Title2:
return 22.0;
case facebook::react::DynamicTypeRamp::Title1:
return 28.0;
case facebook::react::DynamicTypeRamp::LargeTitle:
return 34.0;
}
}
inline static CGFloat RCTEffectiveFontSizeMultiplierFromTextAttributes(const TextAttributes &textAttributes)
{
if (textAttributes.allowFontScaling.value_or(true)) {
if (textAttributes.dynamicTypeRamp.has_value()) {
DynamicTypeRamp dynamicTypeRamp = textAttributes.dynamicTypeRamp.value();
UIFontMetrics *fontMetrics =
[UIFontMetrics metricsForTextStyle:RCTUIFontTextStyleForDynamicTypeRamp(dynamicTypeRamp)];
// Using a specific font size reduces rounding errors from -scaledValueForValue:
CGFloat requestedSize =
isnan(textAttributes.fontSize) ? RCTBaseSizeForDynamicTypeRamp(dynamicTypeRamp) : textAttributes.fontSize;
return [fontMetrics scaledValueForValue:requestedSize] / requestedSize;
} else {
return textAttributes.fontSizeMultiplier;
}
} else {
return 1.0;
}
}
inline static UIFont *RCTEffectiveFontFromTextAttributes(const TextAttributes &textAttributes)
{
NSString *fontFamily = [NSString stringWithCString:textAttributes.fontFamily.c_str() encoding:NSUTF8StringEncoding];
@@ -71,19 +148,11 @@ inline static UIFont *RCTEffectiveFontFromTextAttributes(const TextAttributes &t
fontProperties.weight = textAttributes.fontWeight.has_value()
? RCTUIFontWeightFromInteger((NSInteger)textAttributes.fontWeight.value())
: NAN;
fontProperties.sizeMultiplier =
textAttributes.allowFontScaling.value_or(true) ? textAttributes.fontSizeMultiplier : 1;
fontProperties.sizeMultiplier = RCTEffectiveFontSizeMultiplierFromTextAttributes(textAttributes);
return RCTFontWithFontProperties(fontProperties);
}
inline static CGFloat RCTEffectiveFontSizeMultiplierFromTextAttributes(const TextAttributes &textAttributes)
{
return textAttributes.allowFontScaling.value_or(true) && !isnan(textAttributes.fontSizeMultiplier)
? textAttributes.fontSizeMultiplier
: 1.0;
}
inline static UIColor *RCTEffectiveForegroundColorFromTextAttributes(const TextAttributes &textAttributes)
{
UIColor *effectiveForegroundColor = RCTUIColorFromSharedColor(textAttributes.foregroundColor) ?: [UIColor blackColor];
+19 -10
View File
@@ -2079,7 +2079,7 @@ static float YGDistributeFreeSpaceSecondPass(
const float availableInnerCrossDim,
const float availableInnerWidth,
const float availableInnerHeight,
const bool flexBasisOverflows,
const bool mainAxisOverflows,
const YGMeasureMode measureModeCrossDim,
const bool performLayout,
const YGConfigRef config,
@@ -2175,7 +2175,7 @@ static float YGDistributeFreeSpaceSecondPass(
!YGNodeIsStyleDimDefined(
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
measureModeCrossDim == YGMeasureModeExactly &&
!(isNodeFlexWrap && flexBasisOverflows) &&
!(isNodeFlexWrap && mainAxisOverflows) &&
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
currentRelativeChild->marginLeadingValue(crossAxis).unit !=
YGUnitAuto &&
@@ -2383,7 +2383,7 @@ static void YGResolveFlexibleLength(
const float availableInnerCrossDim,
const float availableInnerWidth,
const float availableInnerHeight,
const bool flexBasisOverflows,
const bool mainAxisOverflows,
const YGMeasureMode measureModeCrossDim,
const bool performLayout,
const YGConfigRef config,
@@ -2411,7 +2411,7 @@ static void YGResolveFlexibleLength(
availableInnerCrossDim,
availableInnerWidth,
availableInnerHeight,
flexBasisOverflows,
mainAxisOverflows,
measureModeCrossDim,
performLayout,
config,
@@ -2884,7 +2884,9 @@ static void YGNodelayoutImpl(
// STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM
float totalOuterFlexBasis = YGNodeComputeFlexBasisForChildren(
// Computed basis + margins + gap
float totalMainDim = 0;
totalMainDim += YGNodeComputeFlexBasisForChildren(
node,
availableInnerWidth,
availableInnerHeight,
@@ -2899,10 +2901,17 @@ static void YGNodelayoutImpl(
depth,
generationCount);
const bool flexBasisOverflows = measureModeMainDim == YGMeasureModeUndefined
? false
: totalOuterFlexBasis > availableInnerMainDim;
if (isNodeFlexWrap && flexBasisOverflows &&
if (childCount > 1) {
totalMainDim +=
node->getGapForAxis(mainAxis, availableInnerCrossDim).unwrap() *
(childCount - 1);
}
const bool mainAxisOverflows =
(measureModeMainDim != YGMeasureModeUndefined) &&
totalMainDim > availableInnerMainDim;
if (isNodeFlexWrap && mainAxisOverflows &&
measureModeMainDim == YGMeasureModeAtMost) {
measureModeMainDim = YGMeasureModeExactly;
}
@@ -3025,7 +3034,7 @@ static void YGNodelayoutImpl(
availableInnerCrossDim,
availableInnerWidth,
availableInnerHeight,
flexBasisOverflows,
mainAxisOverflows,
measureModeCrossDim,
performLayout,
config,
+16 -11
View File
@@ -59,7 +59,6 @@ import typeof Dimensions from './Libraries/Utilities/Dimensions';
import typeof Easing from './Libraries/Animated/Easing';
import typeof ReactNative from './Libraries/Renderer/shims/ReactNative';
import typeof I18nManager from './Libraries/ReactNative/I18nManager';
import typeof ImagePickerIOS from './Libraries/Image/ImagePickerIOS';
import typeof InteractionManager from './Libraries/Interaction/InteractionManager';
import typeof Keyboard from './Libraries/Components/Keyboard/Keyboard';
import typeof LayoutAnimation from './Libraries/LayoutAnimation/LayoutAnimation';
@@ -281,16 +280,6 @@ module.exports = {
get I18nManager(): I18nManager {
return require('./Libraries/ReactNative/I18nManager');
},
get ImagePickerIOS(): ImagePickerIOS {
warnOnce(
'imagePickerIOS-moved',
'ImagePickerIOS has been extracted from react-native core and will be removed in a future release. ' +
"Please upgrade to use either '@react-native-community/react-native-image-picker' or 'expo-image-picker'. " +
"If you cannot upgrade to a different library, please install the deprecated '@react-native-community/image-picker-ios' package. " +
'See https://github.com/rnc-archive/react-native-image-picker-ios',
);
return require('./Libraries/Image/ImagePickerIOS');
},
get InteractionManager(): InteractionManager {
return require('./Libraries/Interaction/InteractionManager');
},
@@ -765,4 +754,20 @@ if (__DEV__) {
);
},
});
/* $FlowFixMe[prop-missing] This is intentional: Flow will error when
* attempting to access ImagePickerIOS. */
/* $FlowFixMe[invalid-export] This is intentional: Flow will error when
* attempting to access ImagePickerIOS. */
Object.defineProperty(module.exports, 'ImagePickerIOS', {
configurable: true,
get() {
invariant(
false,
'ImagePickerIOS has been removed from React Native. ' +
"Please upgrade to use either '@react-native-community/react-native-image-picker' or 'expo-image-picker'. " +
"If you cannot upgrade to a different library, please install the deprecated '@react-native-community/image-picker-ios' package. " +
'See https://github.com/rnc-archive/react-native-image-picker-ios',
);
},
});
}
+53 -15
View File
@@ -1,7 +1,6 @@
{
"name": "react-native",
"private": true,
"version": "1000.0.0",
"version": "0.71.0-rc.2",
"bin": "./cli.js",
"description": "A framework for building native apps using React",
"license": "MIT",
@@ -86,7 +85,7 @@
"prettier": "prettier --write \"./**/*.{js,md,yml,ts,tsx}\"",
"format-check": "prettier --list-different \"./**/*.{js,md,yml,ts,tsx}\"",
"update-lock": "npx yarn-deduplicate",
"docker-setup-android": "docker pull reactnativecommunity/react-native-android:6.0",
"docker-setup-android": "docker pull reactnativecommunity/react-native-android:6.1",
"docker-build-android": "docker build -t reactnativeci/android -f .circleci/Dockerfiles/Dockerfile.android .",
"test-android-run-instrumentation": "docker run --cap-add=SYS_ADMIN -it reactnativeci/android bash .circleci/Dockerfiles/scripts/run-android-docker-instrumentation-tests.sh",
"test-android-run-unit": "docker run --cap-add=SYS_ADMIN -it reactnativeci/android bash .circleci/Dockerfiles/scripts/run-android-docker-unit-tests.sh",
@@ -100,20 +99,16 @@
"test-ios": "./scripts/objc-test.sh test",
"test-typescript": "dtslint types"
},
"workspaces": [
"packages/*",
"repo-config"
],
"peerDependencies": {
"react": "18.2.0"
},
"dependencies": {
"@jest/create-cache-key-function": "^29.2.1",
"@react-native-community/cli": "10.0.0-alpha.2",
"@react-native-community/cli-platform-android": "10.0.0-alpha.2",
"@react-native-community/cli-platform-ios": "10.0.0-alpha.1",
"@react-native-community/cli": "10.0.0-alpha.5",
"@react-native-community/cli-platform-android": "10.0.0-alpha.4",
"@react-native-community/cli-platform-ios": "10.0.0-alpha.3",
"@react-native/assets": "1.0.0",
"@react-native/normalize-color": "2.0.0",
"@react-native/normalize-color": "2.1.0",
"@react-native/polyfills": "2.0.0",
"abort-controller": "^3.0.0",
"anser": "^1.4.9",
@@ -132,7 +127,7 @@
"pretty-format": "^26.5.2",
"promise": "^8.3.0",
"react-devtools-core": "^4.26.1",
"react-native-gradle-plugin": "^0.71.8",
"react-native-gradle-plugin": "^0.71.9",
"react-refresh": "^0.4.0",
"react-shallow-renderer": "^16.15.0",
"regenerator-runtime": "^0.13.2",
@@ -140,13 +135,56 @@
"stacktrace-parser": "^0.1.3",
"use-sync-external-store": "^1.0.0",
"whatwg-fetch": "^3.0.0",
"ws": "^6.2.2"
"ws": "^6.2.2",
"react-native-codegen": "^0.71.3"
},
"devDependencies": {
"flow-bin": "^0.191.0",
"hermes-eslint": "0.8.0",
"react": "18.2.0",
"react-test-renderer": "^18.2.0"
"react-test-renderer": "18.2.0",
"@babel/core": "^7.14.0",
"@babel/eslint-parser": "^7.18.2",
"@babel/generator": "^7.14.0",
"@babel/plugin-transform-regenerator": "^7.0.0",
"@definitelytyped/dtslint": "^0.0.127",
"@react-native-community/eslint-config": "*",
"@react-native-community/eslint-plugin": "*",
"@react-native/eslint-plugin-specs": "^0.71.1",
"@reactions/component": "^2.0.2",
"@types/react": "^18.0.18",
"@typescript-eslint/parser": "^5.30.5",
"async": "^3.2.2",
"clang-format": "^1.8.0",
"connect": "^3.6.5",
"coveralls": "^3.1.1",
"eslint": "^8.19.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-babel": "^5.3.1",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-ft-flow": "^2.0.1",
"eslint-plugin-jest": "^26.5.3",
"eslint-plugin-jsx-a11y": "^6.6.0",
"eslint-plugin-lint": "^1.0.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-native": "^4.0.0",
"eslint-plugin-relay": "^1.8.3",
"inquirer": "^7.1.0",
"jest": "^29.2.1",
"jest-junit": "^10.0.0",
"jscodeshift": "^0.13.1",
"metro-babel-register": "0.73.3",
"metro-memory-fs": "0.73.3",
"mkdirp": "^0.5.1",
"mock-fs": "^5.1.4",
"prettier": "^2.4.1",
"shelljs": "^0.8.5",
"signedsource": "^1.0.0",
"typescript": "4.1.3",
"ws": "^6.2.2",
"yargs": "^17.5.1"
},
"codegenConfig": {
"libraries": [
@@ -166,4 +204,4 @@
}
]
}
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
{
"version": "0.71.0",
"version": "0.71.1",
"name": "@react-native/babel-plugin-codegen",
"description": "Babel plugin to generate native module and view manager code for React Native.",
"repository": {
@@ -0,0 +1,23 @@
load("@fbsource//tools/build_defs/third_party:yarn_defs.bzl", "yarn_workspace")
yarn_workspace(
name = "yarn-workspace",
srcs = glob(
["**/*.js"],
exclude = [
"**/__fixtures__/**",
"**/__flowtests__/**",
"**/__mocks__/**",
"**/__server_snapshot_tests__/**",
"**/__tests__/**",
"**/node_modules/**",
"**/node_modules/.bin/**",
"**/.*",
"**/.*/**",
"**/.*/.*",
"**/*.xcodeproj/**",
"**/*.xcworkspace/**",
],
),
visibility = ["PUBLIC"],
)
@@ -1,6 +1,6 @@
{
"name": "@react-native-community/eslint-config",
"version": "3.1.0",
"version": "3.2.0",
"description": "ESLint config for React Native",
"main": "index.js",
"license": "MIT",
@@ -1,6 +1,6 @@
{
"name": "@react-native-community/eslint-plugin",
"version": "1.2.0",
"version": "1.3.0",
"description": "ESLint rules for @react-native-community/eslint-config",
"main": "index.js",
"repository": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/eslint-plugin-specs",
"version": "0.71.0",
"version": "0.71.1",
"description": "ESLint rules to validate NativeModule and Component Specs",
"main": "index.js",
"repository": {
@@ -1,7 +1,7 @@
{
"name": "@react-native/hermes-inspector-msggen",
"private": true,
"version": "0.71.0",
"version": "0.71.1",
"license": "MIT",
"bin": {
"msggen": "./bin/index.js"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@react-native/normalize-color",
"version": "2.0.0",
"version": "2.1.0",
"description": "Color normalization for React Native.",
"repository": {
"type": "git",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "react-native-codegen",
"version": "0.71.1",
"version": "0.71.3",
"description": "⚛️ Code generation tools for React Native",
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-codegen",
"repository": {
@@ -118,9 +118,10 @@ function serializeArg(
index: number,
resolveAlias: AliasResolver,
): string {
const {typeAnnotation: nullableTypeAnnotation} = arg;
const {typeAnnotation: nullableTypeAnnotation, optional} = arg;
const [typeAnnotation, nullable] =
unwrapNullable<NativeModuleParamTypeAnnotation>(nullableTypeAnnotation);
const isRequired = !optional && !nullable;
let realTypeAnnotation = typeAnnotation;
if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
@@ -130,12 +131,15 @@ function serializeArg(
function wrap(callback: (val: string) => string) {
const val = `args[${index}]`;
const expression = callback(val);
if (nullable) {
return `${val}.isNull() || ${val}.isUndefined() ? std::nullopt : std::make_optional(${expression})`;
if (isRequired) {
return expression;
} else {
let condition = `${val}.isNull() || ${val}.isUndefined()`;
if (optional) {
condition = `count < ${index} || ${condition}`;
}
return `${condition} ? std::nullopt : std::make_optional(${expression})`;
}
return expression;
}
switch (realTypeAnnotation.type) {
@@ -16,6 +16,7 @@ import type {
NativeModuleTypeAnnotation,
NativeModuleFunctionTypeAnnotation,
NativeModulePropertyShape,
NativeModuleAliasMap,
} from '../../CodegenSchema';
import type {AliasResolver} from './Utils';
@@ -28,8 +29,13 @@ type FilesOutput = Map<string, string>;
const ModuleClassDeclarationTemplate = ({
hasteModuleName,
moduleProperties,
}: $ReadOnly<{hasteModuleName: string, moduleProperties: string[]}>) => {
return `class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule {
structs,
}: $ReadOnly<{
hasteModuleName: string,
moduleProperties: string[],
structs: string,
}>) => {
return `${structs}class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule {
protected:
${hasteModuleName}CxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@@ -107,12 +113,14 @@ ${modules.join('\n\n')}
function translatePrimitiveJSTypeToCpp(
nullableTypeAnnotation: Nullable<NativeModuleTypeAnnotation>,
optional: boolean,
createErrorMessage: (typeName: string) => string,
resolveAlias: AliasResolver,
) {
const [typeAnnotation, nullable] = unwrapNullable<NativeModuleTypeAnnotation>(
nullableTypeAnnotation,
);
const isRequired = !optional && !nullable;
let realTypeAnnotation = typeAnnotation;
if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
@@ -120,7 +128,7 @@ function translatePrimitiveJSTypeToCpp(
}
function wrap(type: string) {
return nullable ? `std::optional<${type}>` : type;
return isRequired ? type : `std::optional<${type}>`;
}
switch (realTypeAnnotation.type) {
@@ -184,6 +192,76 @@ function translatePrimitiveJSTypeToCpp(
}
}
function createStructs(
moduleName: string,
aliasMap: NativeModuleAliasMap,
resolveAlias: AliasResolver,
): string {
return Object.keys(aliasMap)
.map(alias => {
const value = aliasMap[alias];
if (value.properties.length === 0) {
return '';
}
const structName = `${moduleName}Base${alias}`;
const templateParameterWithTypename = value.properties
.map((v, i) => 'typename P' + i)
.join(', ');
const templateParameter = value.properties
.map((v, i) => 'P' + i)
.join(', ');
return `#pragma mark - ${structName}
template <${templateParameterWithTypename}>
struct ${structName} {
${value.properties.map((v, i) => ' P' + i + ' ' + v.name).join(';\n')};
bool operator==(const ${structName} &other) const {
return ${value.properties
.map(v => `${v.name} == other.${v.name}`)
.join(' && ')};
}
};
template <${templateParameterWithTypename}>
struct ${structName}Bridging {
static ${structName}<${templateParameter}> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
${structName}<${templateParameter}> result{
${value.properties
.map(
(v, i) =>
` bridging::fromJs<P${i}>(rt, value.getProperty(rt, "${v.name}"), jsInvoker)`,
)
.join(',\n')}};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const ${structName}<${templateParameter}> &value) {
auto result = facebook::jsi::Object(rt);
${value.properties
.map((v, i) => {
if (v.optional) {
return ` if (value.${v.name}) {
result.setProperty(rt, "${v.name}", bridging::toJs(rt, value.${v.name}.value()));
}`;
} else {
return ` result.setProperty(rt, "${v.name}", bridging::toJs(rt, value.${v.name}));`;
}
})
.join('\n')}
return result;
}
};
`;
})
.join('\n');
}
function translatePropertyToCpp(
prop: NativeModulePropertyShape,
resolveAlias: AliasResolver,
@@ -199,6 +277,7 @@ function translatePropertyToCpp(
const paramTypes = propTypeAnnotation.params.map(param => {
const translatedParam = translatePrimitiveJSTypeToCpp(
param.typeAnnotation,
param.optional,
typeName =>
`Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`,
resolveAlias,
@@ -208,6 +287,7 @@ function translatePropertyToCpp(
const returnType = translatePrimitiveJSTypeToCpp(
propTypeAnnotation.returnTypeAnnotation,
false,
typeName => `Unsupported return type for ${prop.name}. Found: ${typeName}`,
resolveAlias,
);
@@ -247,6 +327,7 @@ module.exports = {
moduleNames: [moduleName],
} = nativeModules[hasteModuleName];
const resolveAlias = createAliasResolver(aliases);
const structs = createStructs(moduleName, aliases, resolveAlias);
return [
ModuleClassDeclarationTemplate({
@@ -254,6 +335,7 @@ module.exports = {
moduleProperties: properties.map(prop =>
translatePropertyToCpp(prop, resolveAlias, true),
),
structs,
}),
ModuleSpecClassDeclarationTemplate({
hasteModuleName,
@@ -275,6 +275,25 @@ const SIMPLE_NATIVE_MODULES: SchemaType = {
],
},
},
{
name: 'getValueWithOptionalArg',
optional: false,
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
type: 'PromiseTypeAnnotation',
},
params: [
{
optional: true,
name: 'parameter',
typeAnnotation: {
type: 'GenericObjectTypeAnnotation',
},
},
],
},
},
{
name: 'getEnums',
optional: false,
@@ -1205,73 +1224,6 @@ const REAL_MODULE_EXAMPLE: SchemaType = {
},
moduleNames: ['CameraRollManager'],
},
NativeImagePickerIOS: {
type: 'NativeModule',
aliases: {},
spec: {
properties: [
{
name: 'openCameraDialog',
optional: false,
typeAnnotation: {
type: 'FunctionTypeAnnotation',
returnTypeAnnotation: {
type: 'VoidTypeAnnotation',
},
params: [
{
optional: false,
name: 'config',
typeAnnotation: {
type: 'ObjectTypeAnnotation',
properties: [
{
optional: false,
name: 'unmirrorFrontFacingCamera',
typeAnnotation: {
type: 'BooleanTypeAnnotation',
},
},
{
optional: false,
name: 'videoMode',
typeAnnotation: {
type: 'BooleanTypeAnnotation',
},
},
],
},
},
{
name: 'successCallback',
optional: false,
typeAnnotation: {
type: 'FunctionTypeAnnotation',
params: [],
returnTypeAnnotation: {
type: 'VoidTypeAnnotation',
},
},
},
{
name: 'cancelCallback',
optional: false,
typeAnnotation: {
type: 'FunctionTypeAnnotation',
params: [],
returnTypeAnnotation: {
type: 'VoidTypeAnnotation',
},
},
},
],
},
},
],
},
moduleNames: ['ImagePickerIOS'],
excludedPlatforms: ['android'],
},
NativeExceptionsManager: {
type: 'NativeModule',
aliases: {
@@ -54,7 +54,7 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_optionals(jsi
return jsi::Value::undefined();
}
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_optionalMethod(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->optionalMethod(rt, args[0].asObject(rt), args[1].asObject(rt).asFunction(rt), args[2].asObject(rt).asArray(rt));
static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->optionalMethod(rt, args[0].asObject(rt), args[1].asObject(rt).asFunction(rt), count < 2 || args[2].isNull() || args[2].isUndefined() ? std::nullopt : std::make_optional(args[2].asObject(rt).asArray(rt)));
return jsi::Value::undefined();
}
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getArrays(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
@@ -240,15 +240,6 @@ NativeCameraRollManagerCxxSpecJSI::NativeCameraRollManagerCxxSpecJSI(std::shared
methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {2, __hostFunction_NativeCameraRollManagerCxxSpecJSI_saveToCameraRoll};
methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerCxxSpecJSI_deletePhotos};
}
static jsi::Value __hostFunction_NativeImagePickerIOSCxxSpecJSI_openCameraDialog(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
static_cast<NativeImagePickerIOSCxxSpecJSI *>(&turboModule)->openCameraDialog(rt, args[0].asObject(rt), args[1].asObject(rt).asFunction(rt), args[2].asObject(rt).asFunction(rt));
return jsi::Value::undefined();
}
NativeImagePickerIOSCxxSpecJSI::NativeImagePickerIOSCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"ImagePickerIOS\\", jsInvoker) {
methodMap_[\\"openCameraDialog\\"] = MethodMetadata {3, __hostFunction_NativeImagePickerIOSCxxSpecJSI_openCameraDialog};
}
static jsi::Value __hostFunction_NativeExceptionsManagerCxxSpecJSI_reportFatalException(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
static_cast<NativeExceptionsManagerCxxSpecJSI *>(&turboModule)->reportFatalException(rt, args[0].asString(rt), args[1].asObject(rt).asArray(rt), args[2].asNumber());
return jsi::Value::undefined();
@@ -337,6 +328,9 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithC
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithPromise(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getValueWithPromise(rt, args[0].asBool());
}
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithOptionalArg(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getValueWithOptionalArg(rt, count < 0 || args[0].isNull() || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt)));
}
static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getEnums(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeSampleTurboModuleCxxSpecJSI *>(&turboModule)->getEnums(rt, args[0].asNumber(), args[1].asNumber(), args[2].asString(rt));
}
@@ -354,6 +348,7 @@ NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared
methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValue};
methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithCallback};
methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithPromise};
methodMap_[\\"getValueWithOptionalArg\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithOptionalArg};
methodMap_[\\"getEnums\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getEnums};
}
@@ -87,7 +87,7 @@ protected:
public:
virtual jsi::Object difficult(jsi::Runtime &rt, jsi::Object A) = 0;
virtual void optionals(jsi::Runtime &rt, jsi::Object A) = 0;
virtual void optionalMethod(jsi::Runtime &rt, jsi::Object options, jsi::Function callback, jsi::Array extras) = 0;
virtual void optionalMethod(jsi::Runtime &rt, jsi::Object options, jsi::Function callback, std::optional<jsi::Array> extras) = 0;
virtual void getArrays(jsi::Runtime &rt, jsi::Object options) = 0;
virtual std::optional<jsi::Object> getNullableObject(jsi::Runtime &rt) = 0;
virtual std::optional<jsi::Object> getNullableGenericObject(jsi::Runtime &rt) = 0;
@@ -129,7 +129,7 @@ private:
return bridging::callFromJs<void>(
rt, &T::optionals, jsInvoker_, instance_, std::move(A));
}
void optionalMethod(jsi::Runtime &rt, jsi::Object options, jsi::Function callback, jsi::Array extras) override {
void optionalMethod(jsi::Runtime &rt, jsi::Object options, jsi::Function callback, std::optional<jsi::Array> extras) override {
static_assert(
bridging::getParameterCount(&T::optionalMethod) == 4,
\\"Expected optionalMethod(...) to have 4 parameters\\");
@@ -202,6 +202,36 @@ Map {
namespace facebook {
namespace react {
#pragma mark - SampleTurboModuleCxxBaseObjectAlias
template <typename P0>
struct SampleTurboModuleCxxBaseObjectAlias {
P0 x;
bool operator==(const SampleTurboModuleCxxBaseObjectAlias &other) const {
return x == other.x;
}
};
template <typename P0>
struct SampleTurboModuleCxxBaseObjectAliasBridging {
static SampleTurboModuleCxxBaseObjectAlias<P0> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
SampleTurboModuleCxxBaseObjectAlias<P0> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"x\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const SampleTurboModuleCxxBaseObjectAlias<P0> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"x\\", bridging::toJs(rt, value.x));
return result;
}
};
class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule {
protected:
NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@@ -358,6 +388,54 @@ Map {
namespace facebook {
namespace react {
#pragma mark - AliasTurboModuleBaseOptions
template <typename P0, typename P1, typename P2, typename P3, typename P4>
struct AliasTurboModuleBaseOptions {
P0 offset;
P1 size;
P2 displaySize;
P3 resizeMode;
P4 allowExternalStorage;
bool operator==(const AliasTurboModuleBaseOptions &other) const {
return offset == other.offset && size == other.size && displaySize == other.displaySize && resizeMode == other.resizeMode && allowExternalStorage == other.allowExternalStorage;
}
};
template <typename P0, typename P1, typename P2, typename P3, typename P4>
struct AliasTurboModuleBaseOptionsBridging {
static AliasTurboModuleBaseOptions<P0, P1, P2, P3, P4> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
AliasTurboModuleBaseOptions<P0, P1, P2, P3, P4> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"offset\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"size\\"), jsInvoker),
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"displaySize\\"), jsInvoker),
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"resizeMode\\"), jsInvoker),
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"allowExternalStorage\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const AliasTurboModuleBaseOptions<P0, P1, P2, P3, P4> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"offset\\", bridging::toJs(rt, value.offset));
result.setProperty(rt, \\"size\\", bridging::toJs(rt, value.size));
if (value.displaySize) {
result.setProperty(rt, \\"displaySize\\", bridging::toJs(rt, value.displaySize.value()));
}
if (value.resizeMode) {
result.setProperty(rt, \\"resizeMode\\", bridging::toJs(rt, value.resizeMode.value()));
}
if (value.allowExternalStorage) {
result.setProperty(rt, \\"allowExternalStorage\\", bridging::toJs(rt, value.allowExternalStorage.value()));
}
return result;
}
};
class JSI_EXPORT AliasTurboModuleCxxSpecJSI : public TurboModule {
protected:
AliasTurboModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@@ -435,6 +513,179 @@ Map {
namespace facebook {
namespace react {
#pragma mark - CameraRollManagerBasePhotoIdentifierImage
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
struct CameraRollManagerBasePhotoIdentifierImage {
P0 uri;
P1 playableDuration;
P2 width;
P3 height;
P4 isStored;
P5 filename;
bool operator==(const CameraRollManagerBasePhotoIdentifierImage &other) const {
return uri == other.uri && playableDuration == other.playableDuration && width == other.width && height == other.height && isStored == other.isStored && filename == other.filename;
}
};
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
struct CameraRollManagerBasePhotoIdentifierImageBridging {
static CameraRollManagerBasePhotoIdentifierImage<P0, P1, P2, P3, P4, P5> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
CameraRollManagerBasePhotoIdentifierImage<P0, P1, P2, P3, P4, P5> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"uri\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"playableDuration\\"), jsInvoker),
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"width\\"), jsInvoker),
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"height\\"), jsInvoker),
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"isStored\\"), jsInvoker),
bridging::fromJs<P5>(rt, value.getProperty(rt, \\"filename\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const CameraRollManagerBasePhotoIdentifierImage<P0, P1, P2, P3, P4, P5> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"uri\\", bridging::toJs(rt, value.uri));
result.setProperty(rt, \\"playableDuration\\", bridging::toJs(rt, value.playableDuration));
result.setProperty(rt, \\"width\\", bridging::toJs(rt, value.width));
result.setProperty(rt, \\"height\\", bridging::toJs(rt, value.height));
if (value.isStored) {
result.setProperty(rt, \\"isStored\\", bridging::toJs(rt, value.isStored.value()));
}
result.setProperty(rt, \\"filename\\", bridging::toJs(rt, value.filename));
return result;
}
};
#pragma mark - CameraRollManagerBasePhotoIdentifier
template <typename P0>
struct CameraRollManagerBasePhotoIdentifier {
P0 node;
bool operator==(const CameraRollManagerBasePhotoIdentifier &other) const {
return node == other.node;
}
};
template <typename P0>
struct CameraRollManagerBasePhotoIdentifierBridging {
static CameraRollManagerBasePhotoIdentifier<P0> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
CameraRollManagerBasePhotoIdentifier<P0> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"node\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const CameraRollManagerBasePhotoIdentifier<P0> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"node\\", bridging::toJs(rt, value.node));
return result;
}
};
#pragma mark - CameraRollManagerBasePhotoIdentifiersPage
template <typename P0, typename P1>
struct CameraRollManagerBasePhotoIdentifiersPage {
P0 edges;
P1 page_info;
bool operator==(const CameraRollManagerBasePhotoIdentifiersPage &other) const {
return edges == other.edges && page_info == other.page_info;
}
};
template <typename P0, typename P1>
struct CameraRollManagerBasePhotoIdentifiersPageBridging {
static CameraRollManagerBasePhotoIdentifiersPage<P0, P1> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
CameraRollManagerBasePhotoIdentifiersPage<P0, P1> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"edges\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"page_info\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const CameraRollManagerBasePhotoIdentifiersPage<P0, P1> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"edges\\", bridging::toJs(rt, value.edges));
result.setProperty(rt, \\"page_info\\", bridging::toJs(rt, value.page_info));
return result;
}
};
#pragma mark - CameraRollManagerBaseGetPhotosParams
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct CameraRollManagerBaseGetPhotosParams {
P0 first;
P1 after;
P2 groupName;
P3 groupTypes;
P4 assetType;
P5 maxSize;
P6 mimeTypes;
bool operator==(const CameraRollManagerBaseGetPhotosParams &other) const {
return first == other.first && after == other.after && groupName == other.groupName && groupTypes == other.groupTypes && assetType == other.assetType && maxSize == other.maxSize && mimeTypes == other.mimeTypes;
}
};
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct CameraRollManagerBaseGetPhotosParamsBridging {
static CameraRollManagerBaseGetPhotosParams<P0, P1, P2, P3, P4, P5, P6> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
CameraRollManagerBaseGetPhotosParams<P0, P1, P2, P3, P4, P5, P6> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"first\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"after\\"), jsInvoker),
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"groupName\\"), jsInvoker),
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"groupTypes\\"), jsInvoker),
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"assetType\\"), jsInvoker),
bridging::fromJs<P5>(rt, value.getProperty(rt, \\"maxSize\\"), jsInvoker),
bridging::fromJs<P6>(rt, value.getProperty(rt, \\"mimeTypes\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const CameraRollManagerBaseGetPhotosParams<P0, P1, P2, P3, P4, P5, P6> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"first\\", bridging::toJs(rt, value.first));
if (value.after) {
result.setProperty(rt, \\"after\\", bridging::toJs(rt, value.after.value()));
}
if (value.groupName) {
result.setProperty(rt, \\"groupName\\", bridging::toJs(rt, value.groupName.value()));
}
if (value.groupTypes) {
result.setProperty(rt, \\"groupTypes\\", bridging::toJs(rt, value.groupTypes.value()));
}
if (value.assetType) {
result.setProperty(rt, \\"assetType\\", bridging::toJs(rt, value.assetType.value()));
}
if (value.maxSize) {
result.setProperty(rt, \\"maxSize\\", bridging::toJs(rt, value.maxSize.value()));
}
if (value.mimeTypes) {
result.setProperty(rt, \\"mimeTypes\\", bridging::toJs(rt, value.mimeTypes.value()));
}
return result;
}
};
class JSI_EXPORT NativeCameraRollManagerCxxSpecJSI : public TurboModule {
protected:
NativeCameraRollManagerCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
@@ -505,47 +756,106 @@ private:
Delegate delegate_;
};
class JSI_EXPORT NativeImagePickerIOSCxxSpecJSI : public TurboModule {
protected:
NativeImagePickerIOSCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
public:
virtual void openCameraDialog(jsi::Runtime &rt, jsi::Object config, jsi::Function successCallback, jsi::Function cancelCallback) = 0;
#pragma mark - ExceptionsManagerBaseStackFrame
template <typename P0, typename P1, typename P2, typename P3, typename P4>
struct ExceptionsManagerBaseStackFrame {
P0 column;
P1 file;
P2 lineNumber;
P3 methodName;
P4 collapse;
bool operator==(const ExceptionsManagerBaseStackFrame &other) const {
return column == other.column && file == other.file && lineNumber == other.lineNumber && methodName == other.methodName && collapse == other.collapse;
}
};
template <typename T>
class JSI_EXPORT NativeImagePickerIOSCxxSpec : public TurboModule {
public:
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.get(rt, propName);
template <typename P0, typename P1, typename P2, typename P3, typename P4>
struct ExceptionsManagerBaseStackFrameBridging {
static ExceptionsManagerBaseStackFrame<P0, P1, P2, P3, P4> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
ExceptionsManagerBaseStackFrame<P0, P1, P2, P3, P4> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"column\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"file\\"), jsInvoker),
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"lineNumber\\"), jsInvoker),
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"methodName\\"), jsInvoker),
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"collapse\\"), jsInvoker)};
return result;
}
protected:
NativeImagePickerIOSCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(\\"ImagePickerIOS\\", jsInvoker),
delegate_(static_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeImagePickerIOSCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeImagePickerIOSCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {}
void openCameraDialog(jsi::Runtime &rt, jsi::Object config, jsi::Function successCallback, jsi::Function cancelCallback) override {
static_assert(
bridging::getParameterCount(&T::openCameraDialog) == 4,
\\"Expected openCameraDialog(...) to have 4 parameters\\");
return bridging::callFromJs<void>(
rt, &T::openCameraDialog, jsInvoker_, instance_, std::move(config), std::move(successCallback), std::move(cancelCallback));
static jsi::Object toJs(
jsi::Runtime &rt,
const ExceptionsManagerBaseStackFrame<P0, P1, P2, P3, P4> &value) {
auto result = facebook::jsi::Object(rt);
if (value.column) {
result.setProperty(rt, \\"column\\", bridging::toJs(rt, value.column.value()));
}
result.setProperty(rt, \\"file\\", bridging::toJs(rt, value.file));
if (value.lineNumber) {
result.setProperty(rt, \\"lineNumber\\", bridging::toJs(rt, value.lineNumber.value()));
}
result.setProperty(rt, \\"methodName\\", bridging::toJs(rt, value.methodName));
if (value.collapse) {
result.setProperty(rt, \\"collapse\\", bridging::toJs(rt, value.collapse.value()));
}
return result;
}
};
private:
T *instance_;
};
Delegate delegate_;
#pragma mark - ExceptionsManagerBaseExceptionData
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
struct ExceptionsManagerBaseExceptionData {
P0 message;
P1 originalMessage;
P2 name;
P3 componentStack;
P4 stack;
P5 id;
P6 isFatal;
P7 extraData;
bool operator==(const ExceptionsManagerBaseExceptionData &other) const {
return message == other.message && originalMessage == other.originalMessage && name == other.name && componentStack == other.componentStack && stack == other.stack && id == other.id && isFatal == other.isFatal && extraData == other.extraData;
}
};
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
struct ExceptionsManagerBaseExceptionDataBridging {
static ExceptionsManagerBaseExceptionData<P0, P1, P2, P3, P4, P5, P6, P7> fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
ExceptionsManagerBaseExceptionData<P0, P1, P2, P3, P4, P5, P6, P7> result{
bridging::fromJs<P0>(rt, value.getProperty(rt, \\"message\\"), jsInvoker),
bridging::fromJs<P1>(rt, value.getProperty(rt, \\"originalMessage\\"), jsInvoker),
bridging::fromJs<P2>(rt, value.getProperty(rt, \\"name\\"), jsInvoker),
bridging::fromJs<P3>(rt, value.getProperty(rt, \\"componentStack\\"), jsInvoker),
bridging::fromJs<P4>(rt, value.getProperty(rt, \\"stack\\"), jsInvoker),
bridging::fromJs<P5>(rt, value.getProperty(rt, \\"id\\"), jsInvoker),
bridging::fromJs<P6>(rt, value.getProperty(rt, \\"isFatal\\"), jsInvoker),
bridging::fromJs<P7>(rt, value.getProperty(rt, \\"extraData\\"), jsInvoker)};
return result;
}
static jsi::Object toJs(
jsi::Runtime &rt,
const ExceptionsManagerBaseExceptionData<P0, P1, P2, P3, P4, P5, P6, P7> &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, \\"message\\", bridging::toJs(rt, value.message));
result.setProperty(rt, \\"originalMessage\\", bridging::toJs(rt, value.originalMessage));
result.setProperty(rt, \\"name\\", bridging::toJs(rt, value.name));
result.setProperty(rt, \\"componentStack\\", bridging::toJs(rt, value.componentStack));
result.setProperty(rt, \\"stack\\", bridging::toJs(rt, value.stack));
result.setProperty(rt, \\"id\\", bridging::toJs(rt, value.id));
result.setProperty(rt, \\"isFatal\\", bridging::toJs(rt, value.isFatal));
if (value.extraData) {
result.setProperty(rt, \\"extraData\\", bridging::toJs(rt, value.extraData.value()));
}
return result;
}
};
class JSI_EXPORT NativeExceptionsManagerCxxSpecJSI : public TurboModule {
@@ -668,6 +978,7 @@ public:
virtual jsi::Object getValue(jsi::Runtime &rt, double x, jsi::String y, jsi::Object z) = 0;
virtual void getValueWithCallback(jsi::Runtime &rt, jsi::Function callback) = 0;
virtual jsi::Value getValueWithPromise(jsi::Runtime &rt, bool error) = 0;
virtual jsi::Value getValueWithOptionalArg(jsi::Runtime &rt, std::optional<jsi::Object> parameter) = 0;
virtual jsi::String getEnums(jsi::Runtime &rt, double enumInt, double enumFloat, jsi::String enumString) = 0;
};
@@ -778,6 +1089,14 @@ private:
return bridging::callFromJs<jsi::Value>(
rt, &T::getValueWithPromise, jsInvoker_, instance_, std::move(error));
}
jsi::Value getValueWithOptionalArg(jsi::Runtime &rt, std::optional<jsi::Object> parameter) override {
static_assert(
bridging::getParameterCount(&T::getValueWithOptionalArg) == 2,
\\"Expected getValueWithOptionalArg(...) to have 2 parameters\\");
return bridging::callFromJs<jsi::Value>(
rt, &T::getValueWithOptionalArg, jsInvoker_, instance_, std::move(parameter));
}
jsi::String getEnums(jsi::Runtime &rt, double enumInt, double enumFloat, jsi::String enumString) override {
static_assert(
bridging::getParameterCount(&T::getEnums) == 4,
@@ -711,40 +711,6 @@ namespace facebook {
};
} // namespace react
} // namespace facebook
namespace JS {
namespace NativeImagePickerIOS {
struct SpecOpenCameraDialogConfig {
bool unmirrorFrontFacingCamera() const;
bool videoMode() const;
SpecOpenCameraDialogConfig(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}
@interface RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig)
+ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json;
@end
@protocol NativeImagePickerIOSSpec <RCTBridgeModule, RCTTurboModule>
- (void)openCameraDialog:(JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig &)config
successCallback:(RCTResponseSenderBlock)successCallback
cancelCallback:(RCTResponseSenderBlock)cancelCallback;
@end
namespace facebook {
namespace react {
/**
* ObjC++ class for module 'NativeImagePickerIOS'
*/
class JSI_EXPORT NativeImagePickerIOSSpecJSI : public ObjCTurboModule {
public:
NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams &params);
};
} // namespace react
} // namespace facebook
inline double JS::NativeCameraRollManager::GetPhotosParams::first() const
{
id const p = _v[@\\"first\\"];
@@ -845,16 +811,6 @@ inline id<NSObject> _Nullable JS::NativeExceptionsManager::ExceptionData::extraD
id const p = _v[@\\"extraData\\"];
return p;
}
inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::unmirrorFrontFacingCamera() const
{
id const p = _v[@\\"unmirrorFrontFacingCamera\\"];
return RCTBridgingToBool(p);
}
inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::videoMode() const
{
id const p = _v[@\\"videoMode\\"];
return RCTBridgingToBool(p);
}
",
}
`;
@@ -933,6 +889,9 @@ namespace JS {
- (void)getValueWithPromise:(BOOL)error
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject;
- (void)getValueWithOptionalArg:(NSDictionary *)parameter
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject;
- (NSString *)getEnums:(double)enumInt
enumFloat:(double)enumFloat
enumString:(NSString *)enumString;
@@ -377,6 +377,10 @@ public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaMo
@DoNotStrip
public abstract void getValueWithPromise(boolean error, Promise promise);
@ReactMethod
@DoNotStrip
public abstract void getValueWithOptionalArg(ReadableMap parameter, Promise promise);
@ReactMethod(isBlockingSynchronousMethod = true)
@DoNotStrip
public abstract String getEnums(double enumInt, double enumFloat, String enumString);
@@ -384,6 +384,11 @@ static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getVal
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, \\"getValueWithPromise\\", \\"(ZLcom/facebook/react/bridge/Promise;)V\\", args, count, cachedMethodId);
}
static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithOptionalArg(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
static jmethodID cachedMethodId = nullptr;
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, \\"getValueWithOptionalArg\\", \\"(Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Promise;)V\\", args, count, cachedMethodId);
}
static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getEnums(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
static jmethodID cachedMethodId = nullptr;
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, StringKind, \\"getEnums\\", \\"(DDLjava/lang/String;)Ljava/lang/String;\\", args, count, cachedMethodId);
@@ -402,6 +407,7 @@ NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const JavaTurboMo
methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue};
methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback};
methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise};
methodMap_[\\"getValueWithOptionalArg\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithOptionalArg};
methodMap_[\\"getEnums\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getEnums};
}
@@ -367,27 +367,6 @@ namespace facebook {
}
} // namespace react
} // namespace facebook
@implementation RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig)
+ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json
{
return facebook::react::managedPointer<JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig>(json);
}
@end
namespace facebook {
namespace react {
static facebook::jsi::Value __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, \\"openCameraDialog\\", @selector(openCameraDialog:successCallback:cancelCallback:), args, count);
}
NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams &params)
: ObjCTurboModule(params) {
methodMap_[\\"openCameraDialog\\"] = MethodMetadata {3, __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog};
setMethodArgConversionSelector(@\\"openCameraDialog\\", 0, @\\"JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:\\");
}
} // namespace react
} // namespace facebook
",
}
`;
@@ -453,6 +432,10 @@ namespace facebook {
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithOptionalArg(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithOptionalArg\\", @selector(getValueWithOptionalArg:resolve:reject:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getEnums(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, StringKind, \\"getEnums\\", @selector(getEnums:enumFloat:enumString:), args, count);
}
@@ -494,6 +477,9 @@ namespace facebook {
methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise};
methodMap_[\\"getValueWithOptionalArg\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithOptionalArg};
methodMap_[\\"getEnums\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getEnums};
@@ -1,6 +1,6 @@
{
"name": "react-native-gradle-plugin",
"version": "0.71.8",
"version": "0.71.9",
"description": "⚛️ Gradle Plugin for React Native",
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-gradle-plugin",
"repository": {
@@ -35,9 +35,23 @@ internal object DependencyUtils {
fun configureDependencies(project: Project, versionString: String) {
if (versionString.isBlank()) return
project.configurations.all { configuration ->
// Here we set a dependencySubstitution for both react-native and hermes-engine as those
// coordinates are voided due to https://github.com/facebook/react-native/issues/35210
// This allows users to import libraries that are still using
// implementation("com.facebook.react:react-native:+") and resolve the right dependency.
configuration.resolutionStrategy.dependencySubstitution {
it.substitute(it.module("com.facebook.react:react-native"))
.using(it.module("com.facebook.react:react-android:${versionString}"))
.because(
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.")
it.substitute(it.module("com.facebook.react:hermes-engine"))
.using(it.module("com.facebook.react: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.")
}
configuration.resolutionStrategy.force(
"com.facebook.react:react-native:${versionString}",
"com.facebook.react:hermes-engine:${versionString}",
"com.facebook.react:react-android:${versionString}",
"com.facebook.react:hermes-android:${versionString}",
)
}
}
@@ -177,8 +177,8 @@ class DependencyUtilsTest {
configureDependencies(project, "1.2.3")
val forcedModules = project.configurations.first().resolutionStrategy.forcedModules
assertTrue(forcedModules.any { it.toString() == "com.facebook.react:react-native:1.2.3" })
assertTrue(forcedModules.any { it.toString() == "com.facebook.react:hermes-engine:1.2.3" })
assertTrue(forcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
assertTrue(forcedModules.any { it.toString() == "com.facebook.react:hermes-android:1.2.3" })
}
@Test
+27
View File
@@ -1,3 +1,4 @@
load("@fbsource//tools/build_defs:glob_defs.bzl", "subdir_glob")
load("@fbsource//xplat/hermes/defs:hermes.bzl", "HERMES_BYTECODE_VERSION")
load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native")
load("//tools/build_defs:fb_xplat_platform_specific_rule.bzl", "fb_xplat_platform_specific_rule")
@@ -10,6 +11,7 @@ load("//tools/build_defs/apple:flag_defs.bzl", "get_objc_arc_preprocessor_flags"
load("//tools/build_defs/oss:metro_defs.bzl", "rn_library")
load(
"//tools/build_defs/oss:rn_defs.bzl",
"ANDROID",
"APPLE",
"YOGA_APPLE_TARGET",
"js_library_glob",
@@ -49,6 +51,7 @@ rn_library(
srcs = js_library_glob(
[
"js",
"NativeCxxModuleExample",
"NativeModuleExample",
"NativeComponentExample",
"RCTTest",
@@ -61,10 +64,13 @@ rn_library(
],
),
codegen_components = True,
codegen_modules = True,
labels = [
"pfh:ReactNative_CommonInfrastructurePlaceholder",
],
native_component_spec_name = "AppSpecs",
native_module_android_package_name = "com.facebook.fbreact.specs",
native_module_spec_name = "AppSpecs",
skip_processors = True,
visibility = ["PUBLIC"],
deps = [
@@ -319,3 +325,24 @@ rn_xplat_cxx_library2(
"//xplat/js/react-native-github:RCTFabricComponentViewsBase",
],
)
rn_xplat_cxx_library2(
name = "NativeCxxModuleExample",
srcs = glob(["NativeCxxModuleExample/*.cpp"]),
header_namespace = "",
exported_headers = subdir_glob(
[
("NativeCxxModuleExample", "*.h"),
],
prefix = "NativeCxxModuleExample",
),
fbandroid_compiler_flags = [
"-fexceptions",
"-frtti",
],
platforms = (ANDROID, APPLE),
visibility = ["PUBLIC"],
deps = [
":AppSpecsJSI",
],
)
@@ -0,0 +1,29 @@
# 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.
cmake_minimum_required(VERSION 3.13)
set(CMAKE_VERBOSE_MAKEFILE on)
add_compile_options(
-fexceptions
-frtti
-std=c++17
-Wall
-Wpedantic
-Wno-gnu-zero-variadic-macro-arguments
-DFOLLY_NO_CONFIG=1
-DLOG_TAG=\"ReactNative\")
file(GLOB nativecxxmoduleexample_SRC CONFIGURE_DEPENDS *.cpp)
add_library(nativecxxmoduleexample STATIC ${nativecxxmoduleexample_SRC})
target_include_directories(nativecxxmoduleexample PUBLIC .)
target_include_directories(react_codegen_AppSpecs PUBLIC .)
target_link_libraries(nativecxxmoduleexample
fbjni
jsi
react_nativemodule_core
react_codegen_AppSpecs)
@@ -0,0 +1,110 @@
/*
* 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.
*/
#include "NativeCxxModuleExample.h"
namespace facebook::react {
NativeCxxModuleExample::NativeCxxModuleExample(
std::shared_ptr<CallInvoker> jsInvoker)
: NativeCxxModuleExampleCxxSpec(std::move(jsInvoker)) {}
void NativeCxxModuleExample::getValueWithCallback(
jsi::Runtime &rt,
AsyncCallback<std::string> callback) {
callback({"value from callback!"});
}
std::vector<std::optional<ObjectStruct>> NativeCxxModuleExample::getArray(
jsi::Runtime &rt,
std::vector<std::optional<ObjectStruct>> arg) {
return arg;
}
bool NativeCxxModuleExample::getBool(jsi::Runtime &rt, bool arg) {
return arg;
}
ConstantsStruct NativeCxxModuleExample::getConstants(jsi::Runtime &rt) {
return ConstantsStruct{true, 69, "react-native"};
}
int32_t NativeCxxModuleExample::getEnum(jsi::Runtime &rt, int32_t arg) {
return arg;
}
std::map<std::string, std::optional<int32_t>> NativeCxxModuleExample::getMap(
jsi::Runtime &rt,
std::map<std::string, std::optional<int32_t>> arg) {
return arg;
}
double NativeCxxModuleExample::getNumber(jsi::Runtime &rt, double arg) {
return arg;
}
ObjectStruct NativeCxxModuleExample::getObject(
jsi::Runtime &rt,
ObjectStruct arg) {
return arg;
}
std::set<float> NativeCxxModuleExample::getSet(
jsi::Runtime &rt,
std::set<float> arg) {
return arg;
}
std::string NativeCxxModuleExample::getString(
jsi::Runtime &rt,
std::string arg) {
return arg;
}
std::string NativeCxxModuleExample::getUnion(
jsi::Runtime &rt,
float x,
std::string y,
jsi::Object z) {
std::string result = "x: " + std::to_string(x) + ", y: " + y + ", z: { ";
if (z.hasProperty(rt, "value")) {
result += "value: ";
result += std::to_string(z.getProperty(rt, "value").getNumber());
} else if (z.hasProperty(rt, "low")) {
result += "low: ";
result += z.getProperty(rt, "low").getString(rt).utf8(rt);
}
result += " }";
return result;
}
ValueStruct NativeCxxModuleExample::getValue(
jsi::Runtime &rt,
double x,
std::string y,
ObjectStruct z) {
ValueStruct result{x, y, z};
return result;
}
AsyncPromise<std::string> NativeCxxModuleExample::getValueWithPromise(
jsi::Runtime &rt,
bool error) {
auto promise = AsyncPromise<std::string>(rt, jsInvoker_);
if (error) {
promise.reject("intentional promise rejection");
} else {
promise.resolve("result!");
}
return promise;
}
void NativeCxxModuleExample::voidFunc(jsi::Runtime &rt) {
// Nothing to do
}
} // namespace facebook::react
@@ -0,0 +1,98 @@
/*
* 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.
*/
#pragma once
#if __has_include(<React-Codegen/AppSpecsJSI.h>) // CocoaPod headers on Apple
#include <React-Codegen/AppSpecsJSI.h>
#elif __has_include("AppSpecsJSI.h") // Cmake headers on Android
#include "AppSpecsJSI.h"
#else // BUCK headers
#include <AppSpecs/AppSpecsJSI.h>
#endif
#include <memory>
#include <set>
#include <string>
#include <vector>
namespace facebook::react {
#pragma mark - Structs
using ConstantsStruct =
NativeCxxModuleExampleCxxBaseConstantsStruct<bool, int32_t, std::string>;
template <>
struct Bridging<ConstantsStruct>
: NativeCxxModuleExampleCxxBaseConstantsStructBridging<
bool,
int32_t,
std::string> {};
using ObjectStruct = NativeCxxModuleExampleCxxBaseObjectStruct<
int32_t,
std::string,
std::optional<std::string>>;
template <>
struct Bridging<ObjectStruct>
: NativeCxxModuleExampleCxxBaseObjectStructBridging<
int32_t,
std::string,
std::optional<std::string>> {};
using ValueStruct =
NativeCxxModuleExampleCxxBaseValueStruct<double, std::string, ObjectStruct>;
template <>
struct Bridging<ValueStruct> : NativeCxxModuleExampleCxxBaseValueStructBridging<
double,
std::string,
ObjectStruct> {};
#pragma mark - implementation
class NativeCxxModuleExample
: public NativeCxxModuleExampleCxxSpec<NativeCxxModuleExample> {
public:
NativeCxxModuleExample(std::shared_ptr<CallInvoker> jsInvoker);
void getValueWithCallback(
jsi::Runtime &rt,
AsyncCallback<std::string> callback);
std::vector<std::optional<ObjectStruct>> getArray(
jsi::Runtime &rt,
std::vector<std::optional<ObjectStruct>> arg);
bool getBool(jsi::Runtime &rt, bool arg);
ConstantsStruct getConstants(jsi::Runtime &rt);
int32_t getEnum(jsi::Runtime &rt, int32_t arg);
std::map<std::string, std::optional<int32_t>> getMap(
jsi::Runtime &rt,
std::map<std::string, std::optional<int32_t>> arg);
double getNumber(jsi::Runtime &rt, double arg);
ObjectStruct getObject(jsi::Runtime &rt, ObjectStruct arg);
std::set<float> getSet(jsi::Runtime &rt, std::set<float> arg);
std::string getString(jsi::Runtime &rt, std::string arg);
std::string getUnion(jsi::Runtime &rt, float x, std::string y, jsi::Object z);
ValueStruct
getValue(jsi::Runtime &rt, double x, std::string y, ObjectStruct z);
AsyncPromise<std::string> getValueWithPromise(jsi::Runtime &rt, bool error);
void voidFunc(jsi::Runtime &rt);
};
} // namespace facebook::react
@@ -0,0 +1,64 @@
/**
* 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.
*
* @flow strict-local
* @format
*/
import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
import {TurboModuleRegistry} from 'react-native';
/** FIXME: Enable flow-enum support
export enum EnumInt {
A = 23,
B = 42,
}
*/
export type UnionFloat = 1.44 | 2.88 | 5.76;
export type UnionString = 'One' | 'Two' | 'Three';
export type UnionObject = {value: number} | {low: string};
export type ConstantsStruct = {|
const1: boolean,
const2: number,
const3: string,
|};
export type ObjectStruct = {|
a: number,
b: string,
c?: ?string,
|};
export type ValueStruct = {|
x: number,
y: string,
z: ObjectStruct,
|};
export interface Spec extends TurboModule {
+getArray: (arg: Array<ObjectStruct | null>) => Array<ObjectStruct | null>;
+getBool: (arg: boolean) => boolean;
+getConstants: () => ConstantsStruct;
// FIXME: Enable flow-enum support
+getEnum: (arg: number /*EnumInt*/) => number /*EnumInt*/;
+getMap: (arg: {[key: string]: ?number}) => {[key: string]: ?number};
+getNumber: (arg: number) => number;
+getObject: (arg: ObjectStruct) => ObjectStruct;
+getSet: (arg: Array<number>) => Array<number>;
+getString: (arg: string) => string;
+getUnion: (x: UnionFloat, y: UnionString, z: UnionObject) => string;
+getValue: (x: number, y: string, z: ObjectStruct) => ValueStruct;
+getValueWithCallback: (callback: (value: string) => void) => void;
+getValueWithPromise: (error: boolean) => Promise<string>;
+voidFunc: () => void;
}
export default (TurboModuleRegistry.get<Spec>(
'NativeCxxModuleExampleCxx',
): ?Spec);
@@ -0,0 +1,31 @@
# 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")))
Pod::Spec.new do |s|
s.name = "NativeCxxModuleExample"
s.version = package["version"]
s.summary = package["description"]
s.description = "NativeCxxModuleExample"
s.homepage = "https://github.com/facebook/react-native.git"
s.license = "MIT"
s.platforms = { :ios => "12.4" }
s.compiler_flags = '-Wno-nullability-completeness'
s.author = "Meta Platforms, Inc. and its affiliates"
s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "#{s.version}" }
s.source_files = "**/*.{h,cpp}"
s.requires_arc = true
s.pod_target_xcconfig = {
"USE_HEADERMAP" => "YES",
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
}
install_modules_dependencies(s)
s.dependency "ReactCommon/turbomodule/core"
end
+3
View File
@@ -48,6 +48,9 @@ def pods(target_name, options = {}, use_flipper: !IN_CI && !USE_FRAMEWORKS)
# RNTester native modules and components
pod 'ScreenshotManager', :path => "NativeModuleExample"
if ENV['RCT_NEW_ARCH_ENABLED'] == '1'
pod 'NativeCxxModuleExample', :path => "NativeCxxModuleExample"
end
end
target 'RNTester' do
File diff suppressed because it is too large Load Diff
@@ -7,6 +7,9 @@
#import "RNTesterTurboModuleProvider.h"
#ifdef RCT_NEW_ARCH_ENABLED
#import <NativeCxxModuleExample/NativeCxxModuleExample.h>
#endif
#import <React/CoreModulesPlugins.h>
#import <ReactCommon/RCTSampleTurboModule.h>
#import <ReactCommon/SampleTurboCxxModule.h>
@@ -28,7 +31,11 @@ std::shared_ptr<TurboModule> RNTesterTurboModuleProvider(
if (name == "SampleTurboCxxModule") {
return std::make_shared<SampleTurboCxxModule>(jsInvoker);
}
#ifdef RCT_NEW_ARCH_ENABLED
if (name == "NativeCxxModuleExampleCxx") {
return std::make_shared<NativeCxxModuleExample>(jsInvoker);
}
#endif
return nullptr;
}
+3 -3
View File
@@ -86,8 +86,8 @@ def reactNativeArchitectures() {
}
android {
buildToolsVersion = "31.0.0"
compileSdkVersion 31
buildToolsVersion = "33.0.0"
compileSdkVersion 33
namespace "com.facebook.react.uiapp"
// Used to override the NDK path/version on internal CI or by allowing
@@ -114,7 +114,7 @@ android {
defaultConfig {
applicationId "com.facebook.react.uiapp"
minSdkVersion 21
targetSdkVersion 31
targetSdkVersion 33
versionCode 1
versionName "1.0"
testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type
@@ -11,7 +11,11 @@ project(appmodules)
include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake)
add_subdirectory(${REACT_COMMON_DIR}/react/nativemodule/samples/platform/android/ sampleturbomodule_build)
add_subdirectory(${REACT_COMMON_DIR}/../packages/rn-tester/NativeCxxModuleExample/ nativecxxmoduleexample_build)
# RN Tester needs to link against the sample turbomobule
target_link_libraries(${CMAKE_PROJECT_NAME}
sampleturbomodule)
# RN Tester needs to link against the NativeCxxModuleExample
target_link_libraries(${CMAKE_PROJECT_NAME}
nativecxxmoduleexample)
@@ -8,6 +8,7 @@
#include <AppSpecs.h>
#include <DefaultComponentsRegistry.h>
#include <DefaultTurboModuleManagerDelegate.h>
#include <NativeCxxModuleExample.h>
#include <ReactCommon/SampleTurboModuleSpec.h>
#include <fbjni/fbjni.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
@@ -23,7 +24,16 @@ void registerComponents(
RNTMyNativeViewComponentDescriptor>());
}
std::shared_ptr<TurboModule> provideModules(
std::shared_ptr<TurboModule> cxxModuleProvider(
const std::string &name,
const std::shared_ptr<CallInvoker> &jsInvoker) {
if (name == "NativeCxxModuleExampleCxx") {
return std::make_shared<NativeCxxModuleExample>(jsInvoker);
}
return nullptr;
}
std::shared_ptr<TurboModule> javaModuleProvider(
const std::string &name,
const JavaTurboModule::InitParams &params) {
auto module = AppSpecs_ModuleProvider(name, params);
@@ -42,8 +52,10 @@ std::shared_ptr<TurboModule> provideModules(
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
return facebook::jni::initialize(vm, [] {
facebook::react::DefaultTurboModuleManagerDelegate::
moduleProvidersFromEntryPoint = &facebook::react::provideModules;
facebook::react::DefaultTurboModuleManagerDelegate::cxxModuleProvider =
&facebook::react::cxxModuleProvider;
facebook::react::DefaultTurboModuleManagerDelegate::javaModuleProvider =
&facebook::react::javaModuleProvider;
facebook::react::DefaultComponentsRegistry::
registerComponentDescriptorsFromEntryPoint =
&facebook::react::registerComponents;
@@ -1283,4 +1283,49 @@ exports.examples = [
);
},
},
{
title: 'Dynamic Type (iOS only)',
render: function (): React.Node {
const boldStyle = {fontWeight: 'bold'};
const boxStyle = {
borderWidth: 1,
padding: 8,
margin: 8,
};
return (
<View style={{marginTop: 10, marginBottom: 10}}>
<Text>
Adjust text size in Accessibility settings and watch how the font
sizes change relative to each other.
</Text>
<View style={boxStyle}>
<Text style={boldStyle}>With `dynamicTypeRamp`:</Text>
<Text style={{fontSize: 34}} dynamicTypeRamp="largeTitle">
Large Title
</Text>
<Text style={{fontSize: 28}} dynamicTypeRamp="title1">
Title
</Text>
<Text style={{fontSize: 22}} dynamicTypeRamp="title2">
Title 2
</Text>
<Text style={{fontSize: 20}} dynamicTypeRamp="title3">
Title 3
</Text>
<Text style={{fontSize: 17}} dynamicTypeRamp="body">
Body
</Text>
</View>
<View style={boxStyle}>
<Text style={boldStyle}>Without `dynamicTypeRamp`:</Text>
<Text style={{fontSize: 34}}>Large Title</Text>
<Text style={{fontSize: 28}}>Title</Text>
<Text style={{fontSize: 22}}>Title 2</Text>
<Text style={{fontSize: 20}}>Title 3</Text>
<Text style={{fontSize: 17}}>Body</Text>
</View>
</View>
);
},
},
];
@@ -0,0 +1,222 @@
/**
* 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
* @flow strict-local
*/
import type {RootTag} from 'react-native/Libraries/ReactNative/RootTag';
import {
StyleSheet,
Text,
View,
FlatList,
Platform,
TouchableOpacity,
RootTagContext,
} from 'react-native';
import * as React from 'react';
import NativeCxxModuleExample /*EnumInt,*/ from '../../../NativeCxxModuleExample/NativeCxxModuleExample';
type State = {|
testResults: {
[string]: {
type: string,
value: mixed,
...
},
...
},
|};
type Examples =
| 'callback'
| 'getArray'
| 'getBool'
| 'getConstants'
| 'getEnum'
| 'getMap'
| 'getNumber'
| 'getObject'
| 'getSet'
| 'getString'
| 'getUnion'
| 'getValue'
| 'promise'
| 'rejectPromise'
| 'voidFunc';
class NativeCxxModuleExampleExample extends React.Component<{||}, State> {
static contextType: React$Context<RootTag> = RootTagContext;
state: State = {
testResults: {},
};
// Add calls to methods in TurboModule here
// $FlowFixMe[missing-local-annot]
_tests = {
callback: () =>
NativeCxxModuleExample?.getValueWithCallback(callbackValue =>
this._setResult('callback', callbackValue),
),
getArray: () =>
NativeCxxModuleExample?.getArray([
{a: 1, b: 'foo'},
{a: 2, b: 'bar'},
null,
]),
getBool: () => NativeCxxModuleExample?.getBool(true),
getConstants: () => NativeCxxModuleExample?.getConstants(),
getEnum: () => NativeCxxModuleExample?.getEnum(/*EnumInt.A*/ 2),
getMap: () => NativeCxxModuleExample?.getMap({a: 1, b: null, c: 3}),
getNumber: () => NativeCxxModuleExample?.getNumber(99.95),
getObject: () =>
NativeCxxModuleExample?.getObject({a: 1, b: 'foo', c: null}),
getSet: () => NativeCxxModuleExample?.getSet([1, 1.1, 1.1, 1.1, 2]),
getString: () => NativeCxxModuleExample?.getString('Hello'),
getUnion: () => NativeCxxModuleExample?.getUnion(1.44, 'Two', {low: '12'}),
getValue: () =>
NativeCxxModuleExample?.getValue(5, 'test', {a: 1, b: 'foo'}),
promise: () =>
NativeCxxModuleExample?.getValueWithPromise(false).then(valuePromise =>
this._setResult('promise', valuePromise),
),
rejectPromise: () =>
NativeCxxModuleExample?.getValueWithPromise(true)
.then(() => {})
.catch(e => this._setResult('rejectPromise', e.message)),
voidFunc: () => NativeCxxModuleExample?.voidFunc(),
};
_setResult(
name: string | Examples,
result:
| $FlowFixMe
| void
| Array<$FlowFixMe>
| boolean
| {const1: boolean, const2: number, const3: string}
| number
| {[key: string]: ?number}
| Promise<mixed>
| number
| string,
) {
this.setState(({testResults}) => ({
testResults: {
...testResults,
/* $FlowFixMe[invalid-computed-prop] (>=0.111.0 site=react_native_fb)
* This comment suppresses an error found when Flow v0.111 was
* deployed. To see the error, delete this comment and run Flow. */
[name]: {value: result, type: typeof result},
},
}));
}
_renderResult(name: Examples): React.Node {
const result = this.state.testResults[name] || {};
return (
<View style={styles.result}>
<Text style={[styles.value]}>{JSON.stringify(result.value)}</Text>
<Text style={[styles.type]}>{result.type}</Text>
</View>
);
}
componentDidMount(): void {
if (global.__turboModuleProxy == null) {
throw new Error(
'Cannot load this example because TurboModule is not configured.',
);
}
Object.keys(this._tests).forEach(item =>
this._setResult(item, this._tests[item]()),
);
}
render(): React.Node {
return (
<View style={styles.container}>
<View style={styles.item}>
<TouchableOpacity
style={[styles.column, styles.button]}
onPress={() =>
Object.keys(this._tests).forEach(item =>
this._setResult(item, this._tests[item]()),
)
}>
<Text style={styles.buttonTextLarge}>Run all tests</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => this.setState({testResults: {}})}
style={[styles.column, styles.button]}>
<Text style={styles.buttonTextLarge}>Clear results</Text>
</TouchableOpacity>
</View>
<FlatList
data={Object.keys(this._tests)}
keyExtractor={item => item}
renderItem={({item}) => (
<View style={styles.item}>
<TouchableOpacity
style={[styles.column, styles.button]}
onPress={e => this._setResult(item, this._tests[item]())}>
<Text style={styles.buttonText}>{item}</Text>
</TouchableOpacity>
<View style={[styles.column]}>{this._renderResult(item)}</View>
</View>
)}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
item: {
flexDirection: 'row',
margin: 6,
},
column: {
flex: 2,
justifyContent: 'center',
padding: 3,
},
result: {
alignItems: 'stretch',
justifyContent: 'space-between',
},
value: {
fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
fontSize: 12,
},
type: {
color: '#333',
fontSize: 10,
},
button: {
borderColor: '#444',
padding: 3,
flex: 1,
},
buttonTextLarge: {
textAlign: 'center',
color: 'rgb(0,122,255)',
fontSize: 16,
padding: 6,
},
buttonText: {
color: 'rgb(0,122,255)',
textAlign: 'center',
},
});
module.exports = NativeCxxModuleExampleExample;
@@ -0,0 +1,27 @@
/**
* 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
* @flow
*/
'use strict';
const React = require('react');
const NativeCxxModuleExampleExample = require('./NativeCxxModuleExampleExample');
exports.displayName = (undefined: ?string);
exports.title = 'Cxx TurboModule';
exports.category = 'Basic';
exports.description = 'Usage of Cxx TurboModule';
exports.examples = [
{
title: 'TurboCxxModuleExample',
render: function (): React.Element<any> {
return <NativeCxxModuleExampleExample />;
},
},
];
@@ -284,6 +284,11 @@ const APIs: Array<RNTesterModuleInfo> = [
category: 'Basic',
module: require('../examples/TurboModule/TurboModuleExample'),
},
{
key: 'TurboCxxModuleExample',
category: 'Basic',
module: require('../examples/TurboModule/TurboCxxModuleExample'),
},
];
if (ReactNativeFeatureFlags.shouldEmitW3CPointerEvents()) {
@@ -311,6 +311,10 @@ const APIs: Array<RNTesterModuleInfo> = [
module: require('../examples/TurboModule/TurboModuleExample'),
supportsTVOS: false,
},
{
key: 'TurboCxxModuleExample',
module: require('../examples/TurboModule/TurboCxxModuleExample'),
},
{
key: 'VibrationExample',
module: require('../examples/Vibration/VibrationExample'),
@@ -29,8 +29,5 @@ module.exports = {
ios: {
sourceDir: '.',
},
android: {
sourceDir: '.',
},
},
};
+3 -2
View File
@@ -14,8 +14,9 @@
"@babel/generator": "^7.14.0",
"@babel/plugin-transform-regenerator": "^7.0.0",
"@definitelytyped/dtslint": "^0.0.127",
"@react-native-community/eslint-config": "*",
"@react-native-community/eslint-plugin": "*",
"@react-native/eslint-plugin-specs": "^0.71.0",
"@react-native/eslint-plugin-specs": "^0.71.1",
"@reactions/component": "^2.0.2",
"@types/react": "^18.0.18",
"@typescript-eslint/parser": "^5.30.5",
@@ -46,7 +47,7 @@
"mkdirp": "^0.5.1",
"prettier": "^2.4.1",
"react": "18.2.0",
"react-native-codegen": "^0.71.1",
"react-native-codegen": "^0.71.3",
"react-test-renderer": "18.2.0",
"shelljs": "^0.8.5",
"signedsource": "^1.0.0",
+3 -3
View File
@@ -4,15 +4,15 @@
## ANDROID ##
# Android SDK Build Tools revision
export ANDROID_SDK_BUILD_TOOLS_REVISION=31.0.0
export ANDROID_SDK_BUILD_TOOLS_REVISION=33.0.0
# Android API Level we build with
export ANDROID_SDK_BUILD_API_LEVEL="31"
export ANDROID_SDK_BUILD_API_LEVEL="33"
# Google APIs for Android level
export ANDROID_GOOGLE_API_LEVEL="23"
# Minimum Android API SDK Level we target
export ANDROID_SDK_MINIMUM_API_LEVEL="21"
# Target API SDK level to build for
export ANDROID_SDK_TARGET_API_LEVEL="31"
export ANDROID_SDK_TARGET_API_LEVEL="33"
# Android Image SDK level to install on the emulator
export ANDROID_SYSTEM_IMAGE_API_LEVEL="21"
+253 -22
View File
@@ -7,7 +7,11 @@
* @format
*/
const {parseVersion, isReleaseBranch} = require('../version-utils');
const {
parseVersion,
isReleaseBranch,
validateBuildType,
} = require('../version-utils');
let execResult = null;
jest.mock('shelljs', () => ({
@@ -38,18 +42,53 @@ describe('version-utils', () => {
});
describe('parseVersion', () => {
it('should throw error if invalid match', () => {
it('should throw error if buildType is undefined', () => {
function testInvalidVersion() {
parseVersion('<invalid version>');
parseVersion('v0.10.5');
}
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
`"Unsupported build type: undefined"`,
);
});
it('should throw error if buildType is not `release`, `dry-run` or `nightly`', () => {
function testInvalidVersion() {
parseVersion('v0.10.5', 'invalid_build_type');
}
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
`"Unsupported build type: invalid_build_type"`,
);
});
it('should throw error if invalid match with release', () => {
function testInvalidVersion() {
parseVersion('<invalid version>', 'release');
}
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
`"You must pass a correctly formatted version; couldn't parse <invalid version>"`,
);
});
it('should throw error if invalid match with dry-run', () => {
function testInvalidVersion() {
parseVersion('<invalid version>', 'dry-run');
}
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
`"You must pass a correctly formatted version; couldn't parse <invalid version>"`,
);
});
it('should throw error if invalid match with nightly', () => {
function testInvalidVersion() {
parseVersion('<invalid version>', 'nightly');
}
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
`"You must pass a correctly formatted version; couldn't parse <invalid version>"`,
);
});
it('should parse pre-release version with .', () => {
const {version, major, minor, patch, prerelease} =
parseVersion('0.66.0-rc.4');
it('should parse pre-release version with release and `.`', () => {
const {version, major, minor, patch, prerelease} = parseVersion(
'0.66.0-rc.4',
'release',
);
expect(version).toBe('0.66.0-rc.4');
expect(major).toBe('0');
expect(minor).toBe('66');
@@ -57,9 +96,11 @@ describe('version-utils', () => {
expect(prerelease).toBe('rc.4');
});
it('should parse pre-release version with -', () => {
const {version, major, minor, patch, prerelease} =
parseVersion('0.66.0-rc-4');
it('should parse pre-release version with release and `-`', () => {
const {version, major, minor, patch, prerelease} = parseVersion(
'0.66.0-rc-4',
'release',
);
expect(version).toBe('0.66.0-rc-4');
expect(major).toBe('0');
expect(minor).toBe('66');
@@ -67,8 +108,20 @@ describe('version-utils', () => {
expect(prerelease).toBe('rc-4');
});
it('should reject pre-release version with random prerelease pattern', () => {
function testInvalidVersion() {
parseVersion('0.66.0-something_invalid', 'release');
}
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
`"Version 0.66.0-something_invalid is not valid for Release"`,
);
});
it('should parse stable version', () => {
const {version, major, minor, patch, prerelease} = parseVersion('0.66.0');
const {version, major, minor, patch, prerelease} = parseVersion(
'0.66.0',
'release',
);
expect(version).toBe('0.66.0');
expect(major).toBe('0');
expect(minor).toBe('66');
@@ -77,18 +130,40 @@ describe('version-utils', () => {
});
it('should parse pre-release version from tag', () => {
const {version, major, minor, patch, prerelease} =
parseVersion('v0.66.1-rc.4');
expect(version).toBe('0.66.1-rc.4');
const {version, major, minor, patch, prerelease} = parseVersion(
'v0.66.0-rc.4',
'release',
);
expect(version).toBe('0.66.0-rc.4');
expect(major).toBe('0');
expect(minor).toBe('66');
expect(patch).toBe('1');
expect(patch).toBe('0');
expect(prerelease).toBe('rc.4');
});
it('should reject pre-release version with patch != 0', () => {
function testInvalidVersion() {
parseVersion('0.66.3-rc.4', 'release');
}
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
`"Version 0.66.3-rc.4 is not valid for Release"`,
);
});
it('should reject pre-release version from tag with random prerelease pattern', () => {
function testInvalidVersion() {
parseVersion('v0.66.0-something_invalid', 'release');
}
expect(testInvalidVersion).toThrowErrorMatchingInlineSnapshot(
`"Version 0.66.0-something_invalid is not valid for Release"`,
);
});
it('should parse stable version from tag', () => {
const {version, major, minor, patch, prerelease} =
parseVersion('v0.66.0');
const {version, major, minor, patch, prerelease} = parseVersion(
'v0.66.0',
'release',
);
expect(version).toBe('0.66.0');
expect(major).toBe('0');
expect(minor).toBe('66');
@@ -96,23 +171,179 @@ describe('version-utils', () => {
expect(prerelease).toBeUndefined();
});
it('should parse nightly fake version', () => {
const {version, major, minor, patch, prerelease} = parseVersion('0.0.0');
expect(version).toBe('0.0.0');
it('should reject nightly with no prerelease', () => {
// this should fail
function testInvalidFunction() {
parseVersion('0.0.0', 'nightly');
}
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
`"Version 0.0.0 is not valid for nightlies"`,
);
});
it('should reject nightly with prerelease but wrong version numbers', () => {
// this should fail
function testInvalidFunction() {
parseVersion('1.2.3-pre-release', 'nightly');
}
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
`"Version 1.2.3-pre-release is not valid for nightlies"`,
);
});
it('should parse nightly with 0.0.0 and a prerelease part', () => {
// this should fail
const {version, major, minor, patch, prerelease} = parseVersion(
'0.0.0-pre-release',
'nightly',
);
expect(version).toBe('0.0.0-pre-release');
expect(major).toBe('0');
expect(minor).toBe('0');
expect(patch).toBe('0');
expect(prerelease).toBe('pre-release');
});
it('should parse dryrun with release version', () => {
const {version, major, minor, patch, prerelease} = parseVersion(
'0.7.3',
'dry-run',
);
expect(version).toBe('0.7.3');
expect(major).toBe('0');
expect(minor).toBe('7');
expect(patch).toBe('3');
expect(prerelease).toBeUndefined();
});
it('should parse dryrun fake version', () => {
const {version, major, minor, patch, prerelease} =
parseVersion('1000.0.0');
it('should parse dryrun with prerelease . version', () => {
const {version, major, minor, patch, prerelease} = parseVersion(
'0.20.0-rc.0',
'dry-run',
);
expect(version).toBe('0.20.0-rc.0');
expect(major).toBe('0');
expect(minor).toBe('20');
expect(patch).toBe('0');
expect(prerelease).toBe('rc.0');
});
it('should reject dryrun with prerelease . version with patch different from 0', () => {
function testInvalidFunction() {
parseVersion('0.20.3-rc.0', 'dry-run');
}
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
`"Version 0.20.3-rc.0 is not valid for dry-runs"`,
);
});
it('should parse dryrun with prerelease - version', () => {
const {version, major, minor, patch, prerelease} = parseVersion(
'0.20.0-rc-0',
'dry-run',
);
expect(version).toBe('0.20.0-rc-0');
expect(major).toBe('0');
expect(minor).toBe('20');
expect(patch).toBe('0');
expect(prerelease).toBe('rc-0');
});
it('should reject dryrun with prerelease - version with patch different from 0', () => {
function testInvalidFunction() {
parseVersion('0.20.3-rc-0', 'dry-run');
}
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
`"Version 0.20.3-rc-0 is not valid for dry-runs"`,
);
});
it('should parse dryrun with main version', () => {
const {version, major, minor, patch, prerelease} = parseVersion(
'1000.0.0',
'dry-run',
);
expect(version).toBe('1000.0.0');
expect(major).toBe('1000');
expect(minor).toBe('0');
expect(patch).toBe('0');
expect(prerelease).toBeUndefined();
});
it('should fail for dryrun with v1000.0.1 version', () => {
function testInvalidFunction() {
parseVersion('v1000.0.1', 'dry-run');
}
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
`"Version 1000.0.1 is not valid for dry-runs"`,
);
});
it('should parse dryrun with nightly version', () => {
const {version, major, minor, patch, prerelease} = parseVersion(
'0.0.0-something-else',
'dry-run',
);
expect(version).toBe('0.0.0-something-else');
expect(major).toBe('0');
expect(minor).toBe('0');
expect(patch).toBe('0');
expect(prerelease).toBe('something-else');
});
it('should reject dryrun invalid values', () => {
function testInvalidFunction() {
parseVersion('1000.0.4', 'dry-run');
}
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
`"Version 1000.0.4 is not valid for dry-runs"`,
);
});
it('should reject dryrun for invalid prerelease', () => {
function testInvalidFunction() {
parseVersion('0.6.4-something-else', 'dry-run');
}
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
`"Version 0.6.4-something-else is not valid for dry-runs"`,
);
});
it('should reject dryrun for nightlies with invalid prerelease', () => {
function testInvalidFunction() {
parseVersion('0.0.0', 'dry-run');
}
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
`"Version 0.0.0 is not valid for dry-runs"`,
);
});
});
describe('Validate version', () => {
it('Throw error if the buildType is unknown', () => {
function testInvalidFunction() {
validateBuildType('wrong_build');
}
expect(testInvalidFunction).toThrowErrorMatchingInlineSnapshot(
`"Unsupported build type: wrong_build"`,
);
});
it('Does not throw if the buildType is release', () => {
function testValidCall() {
validateBuildType('release');
}
expect(testValidCall).not.toThrowError();
});
it('Does not throw if the buildType is nightly', () => {
function testValidCall() {
validateBuildType('nightly');
}
expect(testValidCall).not.toThrowError();
});
it('Does not throw if the buildType is dry-run', () => {
function testValidCall() {
validateBuildType('dry-run');
}
expect(testValidCall).not.toThrowError();
});
});
});
+3 -1
View File
@@ -21,6 +21,7 @@ const request = require('request');
const {getBranchName, exitIfNotOnGit} = require('./scm-utils');
const {parseVersion, isReleaseBranch} = require('./version-utils');
const {failIfTagExists} = require('./release-utils');
let argv = yargs
.option('r', {
@@ -75,6 +76,7 @@ async function main() {
);
const token = argv.token;
const releaseVersion = argv.toVersion;
failIfTagExists(releaseVersion, 'release');
const {pushed} = await inquirer.prompt({
type: 'confirm',
@@ -89,7 +91,7 @@ async function main() {
}
let latest = false;
const {version, prerelease} = parseVersion(releaseVersion);
const {version, prerelease} = parseVersion(releaseVersion, 'release');
if (!prerelease) {
const {setLatest} = await inquirer.prompt({
type: 'confirm',
-123
View File
@@ -1,123 +0,0 @@
#!/bin/bash
# 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.
# This script creates a draft GitHub Release using RELEASE_TEMPLATE.md
# as a template and will upload the provided artifacts to the release.
# Install dependencies:
# apt update && apt install -y jq jo
THIS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
REACT_NATIVE_PATH="$THIS_DIR/../.."
GITHUB_OWNER=${CIRCLE_PROJECT_USERNAME:-facebook}
GITHUB_REPO=${CIRCLE_PROJECT_REPONAME:-react-native}
RELEASE_TYPE="$1"; shift
GIT_TAG="$1"; shift
RELEASE_VERSION="$1"; shift
GITHUB_TOKEN="$1"; shift
ARTIFACTS=("$@")
describe_header () {
printf "\\n\\n>>>>> %s\\n\\n\\n" "$1"
}
describe () {
printf "\\n\\n%s\\n\\n" "$1"
}
echoerr () {
echo "$@" 1>&2
}
if [[ $RELEASE_TYPE == "release" ]]; then
describe_header "Preparing to create a GitHub release."
elif [[ $RELEASE_TYPE == "dry-run" ]]; then
describe_header "Preparing to create a GitHub release as a dry-run."
elif [[ $RELEASE_TYPE == "nightly" ]]; then
describe "GitHub Releases are not used with nightlies. Skipping."
exit 0
else
echoerr "Unrecognized release type: $RELEASE_TYPE"
exit 1
fi
# Derive short version string for use in the sample command used
# to create a new RN app in RELEASE_TEMPLATE.md
# 0.69.0-rc.4 -> 0690rc4
RN_SHORT_VERSION=${RELEASE_VERSION//[.-]/}
PRERELEASE=false
if [[ "$RELEASE_VERSION" == *"rc"* ]]; then
PRERELEASE=true
fi
RELEASE_TEMPLATE_PATH="$REACT_NATIVE_PATH/.github/RELEASE_TEMPLATE.md"
if [[ -f $RELEASE_TEMPLATE_PATH ]]; then
# Replace placeholders in template with actual RN version strings
RELEASE_BODY=$(sed -e "s/__VERSION__/$RELEASE_VERSION/g" -e "s/__SHORT_VERSION__/$RN_SHORT_VERSION/g" "$RELEASE_TEMPLATE_PATH")
else
describe "Could not load GitHub Release template. Falling back to placeholder text."
RELEASE_BODY="<!-- TODO: Fill this out using RELEASE_TEMPLATE.md -->"
fi
# Format and encode JSON payload
RELEASE_DATA=$(jo tag_name="$GIT_TAG" name="$RELEASE_VERSION" body="$RELEASE_BODY" draft=true prerelease="$PRERELEASE" generate_release_notes=false)
if [[ ! $RELEASE_DATA ]]; then
echoerr "Could not format release data."
exit 1
fi
# Create GitHub Release draft
describe_header "Creating GitHub release."
describe "Release payload: $RELEASE_DATA"
if [[ $RELEASE_TYPE == "release" ]]; then
CREATE_RELEASE_RESPONSE=$(curl -X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-d "$RELEASE_DATA" \
"https://api.github.com/repos/$GITHUB_OWNER/$GITHUB_REPO/releases"
)
STATUS=$?
if [ $STATUS == 0 ]; then
describe "Created GitHub Release successfully."
RELEASE_ID=$(echo "$CREATE_RELEASE_RESPONSE" | jq '.id')
else
echoerr "Could not create GitHub release, request failed with $STATUS:\n\n$CREATE_RELEASE_RESPONSE"
exit 1
fi
elif [[ $RELEASE_TYPE == "dry-run" ]]; then
describe "Skipping creating GitHub release because dry-run."
fi
# Upload artifacts
describe_header "Uploading artifacts to GitHub release."
for ARTIFACT_PATH in "${ARTIFACTS[@]}"
do
:
# Upload Hermes artifacts to GitHub Release
ARTIFACT_NAME=$(basename "$ARTIFACT_PATH")
describe "Uploading $ARTIFACT_NAME..."
if [[ $RELEASE_TYPE == "release" ]]; then
if curl -X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Content-Length: $(wc -c "$ARTIFACT_PATH" | awk '{print $1}')" \
-H "Content-Type: application/gzip" \
-T "$ARTIFACT_PATH" \
--progress-bar \
"https://uploads.github.com/repos/$GITHUB_OWNER/$GITHUB_REPO/releases/$RELEASE_ID/assets?name=$ARTIFACT_NAME"; then
describe "Uploaded $ARTIFACT_NAME."
else
describe "Could not upload $ARTIFACT_NAME to GitHub release."
fi
elif [[ $RELEASE_TYPE == "dry-run" ]]; then
describe "Skipping $ARTIFACT_NAME upload because dry-run."
fi
done
@@ -458,15 +458,16 @@ class CodegenUtilsTests < Test::Unit::TestCase
].join(' ')
},
'dependencies': {
"FBReactNativeSpec": ["99.98.97"],
"React-jsiexecutor": ["99.98.97"],
"RCT-Folly": ["2021.07.22.00"],
"RCTRequired": ["99.98.97"],
"RCTTypeSafety": ["99.98.97"],
"React-Core": ["99.98.97"],
"React-jsi": ["99.98.97"],
"hermes-engine": ["99.98.97"],
"ReactCommon/turbomodule/core": ["99.98.97"]
"FBReactNativeSpec": [],
"React-jsiexecutor": [],
"RCT-Folly": [],
"RCTRequired": [],
"RCTTypeSafety": [],
"React-Core": [],
"React-jsi": [],
"hermes-engine": [],
"ReactCommon/turbomodule/bridging": [],
"ReactCommon/turbomodule/core": []
}
}
end
@@ -475,8 +476,8 @@ class CodegenUtilsTests < Test::Unit::TestCase
specs = get_podspec_no_fabric_no_script()
specs[:dependencies].merge!({
'React-graphics': ["99.98.97"],
'React-rncore': ["99.98.97"],
'React-graphics': [],
'React-rncore': [],
})
specs[:'script_phases'] = script_phases
@@ -14,16 +14,21 @@ class JSEngineTests < Test::Unit::TestCase
:react_native_path
def setup
File.enable_testing_mode!
@react_native_path = "../.."
podSpy_cleanUp()
end
def teardown
ENV['HERMES_ENGINE_TARBALL_PATH'] = nil
Open3.reset()
Pod::Config.reset()
Pod::UI.reset()
podSpy_cleanUp()
ENV['USE_HERMES'] = '1'
ENV['CI'] = nil
File.reset()
end
# =============== #
@@ -119,4 +124,31 @@ class JSEngineTests < Test::Unit::TestCase
assert_equal($podInvocation["React-hermes"][:path], "../../ReactCommon/hermes")
assert_equal($podInvocation["libevent"][:version], "~> 2.1.12")
end
# ================================= #
# TEST - isBuildingHermesFromSource #
# ================================= #
def test_isBuildingHermesFromSource_whenTarballIsNilAndVersionIsNotNightly_returnTrue
assert_true(is_building_hermes_from_source("1000.0.0", '../..'))
end
def test_isBuildingHermesFromSource_whenTarballIsNilAndInReleaseBranch_returnTrue
ENV['CI'] = 'true'
File.mocked_existing_files(['../../sdks/.hermesversion'])
assert_true(is_building_hermes_from_source("0.999.0", '../..'))
end
def test_isBuildingHermesFromSource_whenTarballIsNotNil_returnFalse
ENV['HERMES_ENGINE_TARBALL_PATH'] = "~/Downloads/hermes-ios-debug.tar.gz"
assert_false(is_building_hermes_from_source("1000.0.0", '../..'))
end
def test_isBuildingHermesFromSource_whenIsNigthly_returnsFalse
assert_false(is_building_hermes_from_source("0.0.0-", '../..'))
end
def test_isBuildingHermesFromSource_whenIsStbleRelease_returnsFalse
assert_false(is_building_hermes_from_source("0.71.0", '../..'))
end
end
@@ -134,6 +134,7 @@ class NewArchitectureTests < Test::Unit::TestCase
{ :dependency_name => "React-Codegen" },
{ :dependency_name => "RCTRequired" },
{ :dependency_name => "RCTTypeSafety" },
{ :dependency_name => "ReactCommon/turbomodule/bridging" },
{ :dependency_name => "ReactCommon/turbomodule/core" }
])
end
-54
View File
@@ -328,60 +328,6 @@ class UtilsTests < Test::Unit::TestCase
assert_equal(pods_projects_mock.save_invocation_count, 1)
end
# ============================================= #
# Test - Fix React-bridging Header Search Paths #
# ============================================= #
def test_fixReactBridgingHeaderSearchPaths_correctlySetsTheHeaderSearchPathsForAllTargets
# Arrange
first_target = prepare_target("FirstTarget")
second_target = prepare_target("SecondTarget")
third_target = TargetMock.new("ThirdTarget", [
BuildConfigurationMock.new("Debug", {
"HEADER_SEARCH_PATHS" => '$(inherited) "${PODS_ROOT}/Headers/Public" '
}),
BuildConfigurationMock.new("Release", {
"HEADER_SEARCH_PATHS" => '$(inherited) "${PODS_ROOT}/Headers/Public" '
}),
], 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.fix_react_bridging_header_search_paths(installer)
# Assert
first_target.build_configurations.each do |config|
assert_equal(config.build_settings["HEADER_SEARCH_PATHS"].strip,
'$(inherited) "$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging" "$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers"'
)
end
second_target.build_configurations.each do |config|
assert_equal(config.build_settings["HEADER_SEARCH_PATHS"].strip,
'$(inherited) "$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging" "$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers"'
)
end
third_target.build_configurations.each do |config|
assert_equal(config.build_settings["HEADER_SEARCH_PATHS"].strip,
'$(inherited) "${PODS_ROOT}/Headers/Public" "$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging" "$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers"'
)
end
end
# ===================================== #
# Test - Apply Xcode14 React-Core patch #
# ===================================== #
+13 -12
View File
@@ -98,31 +98,32 @@ class CodegenUtils
].join(' ')
},
'dependencies': {
"FBReactNativeSpec": [version],
"React-jsiexecutor": [version],
"RCT-Folly": [folly_version],
"RCTRequired": [version],
"RCTTypeSafety": [version],
"React-Core": [version],
"React-jsi": [version],
"ReactCommon/turbomodule/core": [version]
"FBReactNativeSpec": [],
"React-jsiexecutor": [],
"RCT-Folly": [],
"RCTRequired": [],
"RCTTypeSafety": [],
"React-Core": [],
"React-jsi": [],
"ReactCommon/turbomodule/bridging": [],
"ReactCommon/turbomodule/core": []
}
}
if fabric_enabled
spec[:'dependencies'].merge!({
'React-graphics': [version],
'React-rncore': [version],
'React-graphics': [],
'React-rncore': [],
});
end
if hermes_enabled
spec[:'dependencies'].merge!({
'hermes-engine': [version],
'hermes-engine': [], # let React Native decide which version of Hermes Engine to be used. Otherwise, this can create conflicts.
});
else
spec[:'dependencies'].merge!({
'React-jsc': [version],
'React-jsc': [],
});
end
+28 -3
View File
@@ -37,7 +37,7 @@ end
def add_copy_hermes_framework_script_phase(installer, react_native_path)
utils_dir = File.join(react_native_path, "sdks", "hermes-engine", "utils")
phase_name = "[RN]Copy Hermes framework"
phase_name = "[RN] Copy Hermes Framework"
project = installer.generated_aggregate_targets.first.user_project
target = project.targets.first
if target.shell_script_build_phases.none? { |phase| phase.name == phase_name }
@@ -49,8 +49,33 @@ end
def remove_copy_hermes_framework_script_phase(installer, react_native_path)
utils_dir = File.join(react_native_path, "sdks", "hermes-engine", "utils")
phase_name = "[RN]Copy Hermes framework"
phase_name = "[RN] Copy Hermes Framework"
project = installer.generated_aggregate_targets.first.user_project
project.targets.first.shell_script_build_phases.delete_if { |phase| phase.name == phase_name }
target = project.native_targets.first
target.shell_script_build_phases.each do |phase|
if phase.name == phase_name
target.build_phases.delete(phase)
end
end
project.save()
end
def remove_hermesc_build_dir(react_native_path)
%x(rm -rf #{react_native_path}/sdks/hermes-engine/build_host_hermesc)
end
def is_building_hermes_from_source(react_native_version, react_native_path)
if ENV['HERMES_ENGINE_TARBALL_PATH'] != nil
return false
end
isInMain = react_native_version.include?('1000.0.0')
hermestag_file = File.join(react_native_path, "sdks", ".hermesversion")
isInCI = ENV['CI'] === 'true'
isReleaseBranch = File.exist?(hermestag_file) && isInCI
return isInMain || isReleaseBranch
end
+1
View File
@@ -87,6 +87,7 @@ class NewArchitectureHelper
spec.dependency "RCTRequired"
spec.dependency "RCTTypeSafety"
spec.dependency "ReactCommon/turbomodule/bridging"
spec.dependency "ReactCommon/turbomodule/core"
end
end
-12
View File
@@ -107,18 +107,6 @@ class ReactNativePodsUtils
end
end
def self.fix_react_bridging_header_search_paths(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|
# For third party modules who have React-bridging dependency to search correct headers
config.build_settings['HEADER_SEARCH_PATHS'] ||= '$(inherited) '
config.build_settings['HEADER_SEARCH_PATHS'] << '"$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging" '
config.build_settings['HEADER_SEARCH_PATHS'] << '"$(PODS_CONFIGURATION_BUILD_DIR)/React-bridging/react_bridging.framework/Headers" '
end
end
end
def self.apply_mac_catalyst_patches(installer)
# Fix bundle signing issues
installer.pods_project.targets.each do |target|
@@ -26,7 +26,7 @@ describe('generateSpec', () => {
const outputDirectory = normalize('app/ios/build/generated/ios');
const libraryName = 'library';
const packageName = 'com.library';
const generators = ['componentsIOS', 'modulesIOS'];
const generators = ['componentsIOS', 'modulesIOS', 'modulesCxx'];
jest.mock('fs', () => ({
readFileSync: (path, encoding) => {
@@ -17,16 +17,16 @@ const RNCodegen = utils.getCodegen();
const GENERATORS = {
all: {
android: ['componentsAndroid', 'modulesAndroid'],
ios: ['componentsIOS', 'modulesIOS'],
android: ['componentsAndroid', 'modulesAndroid', 'modulesCxx'],
ios: ['componentsIOS', 'modulesIOS', 'modulesCxx'],
},
components: {
android: ['componentsAndroid'],
ios: ['componentsIOS'],
},
modules: {
android: ['modulesAndroid'],
ios: ['modulesIOS'],
android: ['modulesAndroid', 'modulesCxx'],
ios: ['modulesIOS', 'modulesCxx'],
},
};
+3 -20
View File
@@ -387,30 +387,15 @@ describe('hermes-utils', () => {
describe('getHermesPrebuiltArtifactsTarballName', () => {
it('should return Hermes prebuilts tarball name', () => {
expect(
getHermesPrebuiltArtifactsTarballName('Debug', '1000.0.0'),
).toEqual('hermes-runtime-darwin-debug-v1000.0.0.tar.gz');
expect(getHermesPrebuiltArtifactsTarballName('Debug')).toEqual(
'hermes-ios-debug.tar.gz',
);
});
it('should throw if build type is undefined', () => {
expect(() => {
getHermesPrebuiltArtifactsTarballName();
}).toThrow('Did not specify build type.');
});
it('should throw if release version is undefined', () => {
expect(() => {
getHermesPrebuiltArtifactsTarballName('Release');
}).toThrow('Did not specify release version.');
});
it('should return debug Hermes prebuilts tarball name for RN 0.70.0', () => {
expect(
getHermesPrebuiltArtifactsTarballName('Debug', '0.70.0'),
).toEqual('hermes-runtime-darwin-debug-v0.70.0.tar.gz');
});
it('should return a wildcard Hermes prebuilts tarball name for any RN version', () => {
expect(getHermesPrebuiltArtifactsTarballName('Debug', '*')).toEqual(
'hermes-runtime-darwin-debug-v*.tar.gz',
);
});
});
describe('createHermesPrebuiltArtifactsTarball', () => {
@@ -426,7 +411,6 @@ describe('hermes-utils', () => {
const tarballOutputPath = createHermesPrebuiltArtifactsTarball(
path.join(SDKS_DIR, 'hermes'),
'Debug',
'1000.0.0',
tarballOutputDir,
excludeDebugSymbols,
);
@@ -448,7 +432,6 @@ describe('hermes-utils', () => {
const tarballOutputPath = createHermesPrebuiltArtifactsTarball(
path.join(SDKS_DIR, 'hermes'),
'Debug',
'1000.0.0',
tarballOutputDir,
excludeDebugSymbols,
);

Some files were not shown because too many files have changed in this diff Show More