Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert library to TurboModule #910

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
be521e4
Init FabricExample
j-piasecki Feb 6, 2023
1ede6e7
Use next implementation in the example app
j-piasecki Feb 7, 2023
125cee4
Add spec and configure codegen
j-piasecki Feb 6, 2023
d7a1927
Setup new arch support
j-piasecki Feb 6, 2023
466b93e
iOS implementation
j-piasecki Feb 6, 2023
874d715
Android implementation (for java version)
j-piasecki Feb 6, 2023
f284faf
Use java package when next is disabled
j-piasecki Feb 7, 2023
851d817
Add kotlin package
j-piasecki Feb 7, 2023
1a5587a
Update kotlin module
j-piasecki Feb 7, 2023
1a99729
Compatibility with the old arch
j-piasecki Feb 7, 2023
c4757c0
Don't look for module with old android name
j-piasecki Feb 7, 2023
db4da7b
Update dependencies, remove `react-native-macos`
j-piasecki Feb 9, 2023
0e6a420
Update `react-native.config.js`
j-piasecki Feb 9, 2023
d82c80f
Add workaround for codegened files not being included
j-piasecki Feb 9, 2023
abed02f
Enable new arch in the example app
j-piasecki Feb 9, 2023
d2c56ef
Remove FabricExample
j-piasecki Feb 9, 2023
6007b94
Merge branch 'master' into @jpiasecki/turbomodule
j-piasecki Feb 9, 2023
a39a698
Bump gradle version
j-piasecki Feb 9, 2023
109011e
Rename variable
j-piasecki Feb 9, 2023
c6be49f
Merge remote-tracking branch 'origin/master' into @jpiasecki/turbomodule
Jun 13, 2023
47eaff3
TM working on iOS
Jun 14, 2023
6d2faaa
Turbomodule working on macOS
Jun 14, 2023
8a47c53
Revert changes to codegen config
Jun 14, 2023
11228e5
Merge remote-tracking branch 'origin/master' into @shwanton/turbomodu…
Jun 20, 2023
25157ea
Don't default to new arch when building iOS/macOS
Jun 20, 2023
51b91b2
Revert changes to babel config
Jun 20, 2023
f18666b
Revert version bump
Jun 20, 2023
509b4bc
Update RNCAsyncStorage.podspec
j-piasecki Jun 21, 2023
a1cbaeb
Remove devDependencies
j-piasecki Jun 21, 2023
6f50030
Revert space
j-piasecki Jun 21, 2023
2b07b10
Revert `build.gradle` changes
j-piasecki Jun 21, 2023
1169935
Don't add codegen directory manually
j-piasecki Jun 21, 2023
e6ed072
Use `install_modules_dependencies`
j-piasecki Jun 21, 2023
16b2165
Remove support for RN <0.71 on Android
j-piasecki Jun 21, 2023
7bcb08b
Revert module resolution
j-piasecki Jun 21, 2023
31d0da2
Merge branch 'master' into @shwanton/turbomodule-ios-working
Jun 23, 2023
2e93938
Update `build.gradle` and workflow
j-piasecki Jun 30, 2023
b84f11e
Remove `ViewManagerOnDemandReactPackage`
j-piasecki Jun 30, 2023
0d41f20
Mention updating in comment
j-piasecki Jun 30, 2023
f4edc00
Rename `paper` -> `oldarch`
j-piasecki Jun 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
yarn bundle:ios --dev false
- name: Install Pods
run: |
pod install
RCT_NEW_ARCH_ENABLED=1 pod install
working-directory: example/ios
- name: Boot simulator
run: |
Expand Down Expand Up @@ -109,7 +109,7 @@ jobs:
yarn bundle:macos
- name: Install Pods
run: |
pod install
RCT_NEW_ARCH_ENABLED=1 pod install
working-directory: example/macos
- name: Build
run: |
Expand Down
22 changes: 19 additions & 3 deletions RNCAsyncStorage.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ require 'json'

package = JSON.parse(File.read(File.join(__dir__, 'package.json')))

fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'

Pod::Spec.new do |s|
s.name = "RNCAsyncStorage"
s.version = package['version']
Expand All @@ -10,10 +12,24 @@ Pod::Spec.new do |s|

s.authors = package['author']
s.homepage = package['homepage']
s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.14" }

s.source = { :git => "https://github.com/react-native-async-storage/async-storage.git", :tag => "v#{s.version}" }
s.source_files = "ios/**/*.{h,m}"
s.source_files = "ios/**/*.{h,m,mm}"

if fabric_enabled
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'

s.pod_target_xcconfig = {
'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/boost" "$(PODS_ROOT)/boost-for-react-native" "$(PODS_ROOT)/RCT-Folly"',
'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17',
}
s.platforms = { ios: '13.4', tvos: '11.0', :osx => "10.15" }
s.compiler_flags = folly_compiler_flags + ' -DRCT_NEW_ARCH_ENABLED'

install_modules_dependencies(s)
else
s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.14" }
krizzu marked this conversation as resolved.
Show resolved Hide resolved

s.dependency 'React-Core'
s.dependency "React-Core"
end
end
39 changes: 37 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ def getVersionOrDefault(String flagName, String defaultVersion) {
rootProject.hasProperty(flagName) ? rootProject.properties[flagName] : defaultVersion
}

def isNewArchitectureEnabled() {
// To opt-in for the New Architecture, you can either:
// - Set `newArchEnabled` to true inside the `gradle.properties` file
// - Invoke gradle with `-newArchEnabled=true`
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}

configurations {
compileClasspath
}
Expand Down Expand Up @@ -73,8 +81,22 @@ if (useNextStorage) {
apply from: './testresults.gradle'
}

if (isNewArchitectureEnabled()) {
apply plugin: "com.facebook.react"
}

android {
compileSdkVersion safeExtGet('compileSdkVersion', 32)
// Used to override the NDK path/version by allowing users to customize
// the NDK path/version from their root project (e.g. for M1 support)
if (rootProject.hasProperty("ndkPath")) {
ndkPath rootProject.ext.ndkPath
}
if (rootProject.hasProperty("ndkVersion")) {
ndkVersion rootProject.ext.ndkVersion
}


defaultConfig {
minSdkVersion safeExtGet('minSdkVersion', 23)
targetSdkVersion safeExtGet('targetSdkVersion', 32)
Expand All @@ -94,6 +116,20 @@ android {
}
}
}

sourceSets.main {
java {
if (useNextStorage) {
srcDirs += 'src/kotlinPackage/java'
} else {
srcDirs += 'src/javaPackage/java'
}

if (!isNewArchitectureEnabled()) {
srcDirs += 'src/oldarch/java'
}
}
}
}

repositories {
Expand Down Expand Up @@ -137,6 +173,5 @@ dependencies {
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesTest_version"
}

//noinspection GradleDynamicVersion
implementation 'com.facebook.react:react-native:+' // From node_modules
implementation 'com.facebook.react:react-native:+' // from node_modules
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

package com.reactnativecommunity.asyncstorage;

import com.facebook.react.TurboReactPackage;
import com.facebook.react.ViewManagerOnDemandReactPackage;
import com.facebook.react.bridge.ModuleSpec;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.module.annotations.ReactModuleList;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.uimanager.ViewManager;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

@ReactModuleList(
nativeModules = {
AsyncStorageModule.class,
}
)
public class AsyncStoragePackage extends TurboReactPackage {

@Override
protected List<ModuleSpec> getViewManagers(ReactApplicationContext reactContext) {
return null;
}

@Override
public NativeModule getModule(String name, @Nonnull ReactApplicationContext reactContext) {
switch (name) {
case AsyncStorageModule.NAME:
return new AsyncStorageModule(reactContext);
default:
return null;
}
}

@Override
public ReactModuleInfoProvider getReactModuleInfoProvider() {
try {
Class<?> reactModuleInfoProviderClass =
Class.forName("com.reactnativecommunity.asyncstorage.AsyncStoragePackage$$ReactModuleInfoProvider");
return (ReactModuleInfoProvider) reactModuleInfoProviderClass.newInstance();
} catch (ClassNotFoundException e) {
// ReactModuleSpecProcessor does not run at build-time. Create this ReactModuleInfoProvider by
// hand.
return new ReactModuleInfoProvider() {
@Override
public Map<String, ReactModuleInfo> getReactModuleInfos() {
final Map<String, ReactModuleInfo> reactModuleInfoMap = new HashMap<>();

Class<? extends NativeModule>[] moduleList =
new Class[] {
AsyncStorageModule.class,
};

for (Class<? extends NativeModule> moduleClass : moduleList) {
ReactModule reactModule = moduleClass.getAnnotation(ReactModule.class);

reactModuleInfoMap.put(
reactModule.name(),
new ReactModuleInfo(
reactModule.name(),
moduleClass.getName(),
reactModule.canOverrideExistingModule(),
reactModule.needsEagerInit(),
reactModule.hasConstants(),
reactModule.isCxxModule(),
TurboModule.class.isAssignableFrom(moduleClass)));
}

return reactModuleInfoMap;
}
};
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(
"No ReactModuleInfoProvider for com.reactnativecommunity.asyncstorage.AsyncStoragePackage$$ReactModuleInfoProvider", e);
}
}

// Deprecated in RN 0.47
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}

@Override
@SuppressWarnings("rawtypes")
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.reactnativecommunity.asyncstorage

import com.facebook.react.TurboReactPackage
import com.facebook.react.ViewManagerOnDemandReactPackage
import com.facebook.react.bridge.ModuleSpec
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.module.annotations.ReactModuleList
import com.facebook.react.module.model.ReactModuleInfo
import com.facebook.react.module.model.ReactModuleInfoProvider
import com.facebook.react.turbomodule.core.interfaces.TurboModule
import com.facebook.react.uimanager.ReactShadowNode
import com.facebook.react.uimanager.ViewManager
import com.reactnativecommunity.asyncstorage.next.StorageModule

@ReactModuleList(
nativeModules = [
StorageModule::class
]
)
class AsyncStoragePackage : TurboReactPackage() {
override fun getModule(name: String, context: ReactApplicationContext): NativeModule? = when (name) {
StorageModule.NAME -> StorageModule(context)
else -> null
}

override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
try {
val reactModuleInfoProviderClass =
Class.forName("com.reactnativecommunity.asyncstorage.AsyncStoragePackage$\$ReactModuleInfoProvider")
return reactModuleInfoProviderClass.newInstance() as ReactModuleInfoProvider
} catch (e: ClassNotFoundException) {
return ReactModuleInfoProvider {
val reactModule: ReactModule = StorageModule::class.java.getAnnotation(
ReactModule::class.java)!!

mutableMapOf(
StorageModule.NAME to ReactModuleInfo(
reactModule.name,
StorageModule::class.java.name,
reactModule.canOverrideExistingModule,
reactModule.needsEagerInit,
reactModule.hasConstants,
reactModule.isCxxModule,
TurboModule::class.java.isAssignableFrom(StorageModule::class.java)
)
)
}
} catch (e: InstantiationException) {
throw RuntimeException("No ReactModuleInfoProvider for AsyncStoragePackage$\$ReactModuleInfoProvider", e)
} catch (e: IllegalAccessException) {
throw RuntimeException("No ReactModuleInfoProvider for AsyncStoragePackage$\$ReactModuleInfoProvider", e)
}
}

override fun getViewManagers(reactContext: ReactApplicationContext?): MutableList<ModuleSpec>? = null
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@

@ReactModule(name = AsyncStorageModule.NAME)
public final class AsyncStorageModule
extends ReactContextBaseJavaModule implements ModuleDataCleaner.Cleanable, LifecycleEventListener {
extends NativeAsyncStorageModuleSpec implements ModuleDataCleaner.Cleanable, LifecycleEventListener {

// changed name to not conflict with AsyncStorage from RN repo
public static final String NAME = "RNC_AsyncSQLiteDBStorage";
public static final String NAME = "RNCAsyncStorage";

// SQL variable number limit, defined by SQLITE_LIMIT_VARIABLE_NUMBER:
// https://raw.githubusercontent.com/android/platform_external_sqlite/master/dist/sqlite3.c
Expand Down Expand Up @@ -110,6 +110,7 @@ public void onHostDestroy() {
* (key, null) for the keys that haven't been found.
*/
@ReactMethod
@Override
public void multiGet(final ReadableArray keys, final Callback callback) {
if (keys == null) {
callback.invoke(AsyncStorageErrorUtil.getInvalidKeyError(null), null);
Expand Down Expand Up @@ -183,6 +184,7 @@ protected void doInBackgroundGuarded(Void... params) {
* The insertion will replace conflicting (key, value) pairs.
*/
@ReactMethod
@Override
public void multiSet(final ReadableArray keyValueArray, final Callback callback) {
if (keyValueArray.size() == 0) {
callback.invoke();
Expand Down Expand Up @@ -248,6 +250,7 @@ protected void doInBackgroundGuarded(Void... params) {
* Removes all rows of the keys given.
*/
@ReactMethod
@Override
public void multiRemove(final ReadableArray keys, final Callback callback) {
if (keys.size() == 0) {
callback.invoke();
Expand Down Expand Up @@ -300,6 +303,7 @@ protected void doInBackgroundGuarded(Void... params) {
* of the given keys, if they exist.
*/
@ReactMethod
@Override
public void multiMerge(final ReadableArray keyValueArray, final Callback callback) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@Override
Expand Down Expand Up @@ -362,6 +366,7 @@ protected void doInBackgroundGuarded(Void... params) {
* Clears the database.
*/
@ReactMethod
@Override
public void clear(final Callback callback) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@Override
Expand All @@ -385,6 +390,7 @@ protected void doInBackgroundGuarded(Void... params) {
* Returns an array with all keys from the database.
*/
@ReactMethod
@Override
public void getAllKeys(final Callback callback) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@Override
Expand Down
Loading