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

Add jsi support for newer react native versions(old-arch) #1854

Merged
merged 4 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
107 changes: 16 additions & 91 deletions docs-website/docs/docs/Installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ protected List<ReactPackage> getPackages() {

<details>
<summary>Using with react-native-screens or react-native-gesture-handler</summary>
If you are using recent versions of react-native-screens or react-native-gesture-handler,
you will need to set the kotlin version to 1.5.20 or above (see section above)
If you are using recent versions of react-native-screens or react-native-gesture-handler, you will
need to set the kotlin version to 1.5.20 or above (see section above)
</details>

<details>
Expand Down Expand Up @@ -168,116 +168,41 @@ additional steps manually.
```
// ...
import com.nozbe.watermelondb.jsi.WatermelonDBJSIPackage; // ⬅️ This!
import com.facebook.react.bridge.JSIModulePackage; // ⬅️ This!
// ...
private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(this) {
// ...

@Override
protected JSIModulePackage getJSIModulePackage() {
return new WatermelonDBJSIPackage(); // ⬅️ This!
}
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
// new MyReactNativePackage(),
new WatermelonDBJSIPackage() // ⬅️ Here!
);
}

```

</TabItem>
<TabItem value="kotlin" label="Kotlin">

```
// ...
// ...
import com.nozbe.watermelondb.jsi.WatermelonDBJSIPackage // ⬅️ This!
import com.facebook.react.bridge.JSIModulePackage // ⬅️ This!
// ...
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
// ..
override fun getJSIModulePackage(): JSIModulePackage {
return WatermelonDBJSIPackage()
override fun getPackages(): List<ReactPackage> {
return PackageList(this).packages.apply {
// Packages that cannot be autolinked yet can be added manually here, for example:
// add(new MyReactNativePackage());
add(WatermelonDBJSIPackage())
}
}
}

```

</TabItem>
</Tabs>

or if you have **multiple** JSI Packages (for example, when using `reanimated`):

<Tabs>
<TabItem value="java" label="Java" default>

```
// ...
import java.util.Arrays; // ⬅️ This!
import com.facebook.react.bridge.JSIModuleSpec; // ⬅️ This!
import com.facebook.react.bridge.JSIModulePackage; // ⬅️ This!
import com.facebook.react.bridge.ReactApplicationContext; // ⬅️ This!
import com.facebook.react.bridge.JavaScriptContextHolder; // ⬅️ This!
import com.nozbe.watermelondb.jsi.WatermelonDBJSIPackage; // ⬅️ This!
// ...
private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(this) {
// ...

@Override
protected JSIModulePackage getJSIModulePackage() {
return new JSIModulePackage() {
@Override
public List<JSIModuleSpec> getJSIModules(
final ReactApplicationContext reactApplicationContext,
final JavaScriptContextHolder jsContext
) {
List<JSIModuleSpec> modules = Arrays.asList();

modules.addAll(new WatermelonDBJSIPackage().getJSIModules(reactApplicationContext, jsContext)); // ⬅️ This!
// ⬅️ add more JSI packages here by conventions above, for example:
// modules.addAll(new ReanimatedJSIModulePackage().getJSIModules(reactApplicationContext, jsContext));

return modules;
}
};
}
}
```

</TabItem>
<TabItem value="kotlin" label="Kotlin">

```
// ...
import java.util.Arrays // ⬅️ This!
import com.facebook.react.bridge.JSIModule // ⬅️ This!
import com.facebook.react.bridge.JSIModuleSpec // ⬅️ This!
import com.facebook.react.bridge.JSIModulePackage // ⬅️ This!
import com.facebook.react.bridge.ReactApplicationContext // ⬅️ This!
import com.facebook.react.bridge.JavaScriptContextHolder // ⬅️ This!
import com.nozbe.watermelondb.jsi.WatermelonDBJSIPackage // ⬅️ This!
// ...

class MainApplication : Application(), ReactApplication {

override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
// ...
override fun getJSIModulePackage(): JSIModulePackage {
return JSIModulePackage { reactApplicationContext, jsContext ->
val modules = mutableListOf<JSIModuleSpec<JSIModule>>()

// Add WatermelonDB JSI package
modules.addAll(WatermelonDBJSIPackage().getJSIModules(reactApplicationContext, jsContext))
// Add more JSI packages here by conventions above, for example:
// modules.addAll(ReanimatedJSIModulePackage().getJSIModules(reactApplicationContext, jsContext))

modules
}
}
}
}
```

</TabItem>
</Tabs>

#### Troubleshooting JSI issues
Expand Down
6 changes: 6 additions & 0 deletions docs-website/docs/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ The result is fully reactive! Whenever a post or comment is added, changed, or r

<br/>

<a href="https://learnthewords.app/">
<img src="https://github.com/Nozbe/WatermelonDB/raw/master/assets/apps/learn-the-words.png" alt="Learn The Words" width="300" />
</a>

<br/>

_Does your company or app use 🍉? Open a pull request and add your logo/icon with link here!_

## Contributing
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.nozbe.watermelondb.jsi;

import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.JavaScriptContextHolder;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;

@ReactModule(name = WatermelonDBJSIModule.NAME)
public class WatermelonDBJSIModule extends ReactContextBaseJavaModule {
ReactApplicationContext reactContext;
public static final String NAME = "WMDatabaseJSIBridge";

public WatermelonDBJSIModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}

@NonNull
@Override
public String getName() {
return NAME;
}

@ReactMethod(isBlockingSynchronousMethod = true)
public boolean install() {
try {
JavaScriptContextHolder jsContext = getReactApplicationContext().getJavaScriptContextHolder();
JSIInstaller.install(getReactApplicationContext(), jsContext.get());
Log.i(NAME, "Successfully installed Watermelon DB JSI Bindings!");
return true;
} catch (Exception exception) {
Log.e(NAME, "Failed to install Watermelon DB JSI Bindings!", exception);
return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
package com.nozbe.watermelondb.jsi;

import com.facebook.react.bridge.JSIModulePackage;
import com.facebook.react.bridge.JSIModuleSpec;
import com.facebook.react.bridge.JavaScriptContextHolder;
import androidx.annotation.NonNull;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class WatermelonDBJSIPackage implements JSIModulePackage {
@Override
public List<JSIModuleSpec> getJSIModules(ReactApplicationContext reactApplicationContext, JavaScriptContextHolder jsContextHolder) {
synchronized(jsContextHolder) {
JSIInstaller.install(reactApplicationContext.getApplicationContext(), jsContextHolder.get());
public class WatermelonDBJSIPackage implements ReactPackage {

@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactAppContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new WatermelonDBJSIModule(reactAppContext));
return modules;
}

@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactAppContext) {
return Collections.emptyList();
}
return Arrays.asList();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,7 @@ class MainApplication : Application(), ReactApplication {
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG

override fun getPackages(): List<ReactPackage> =
listOf(MainReactPackage(), NativeModulesPackage(), WatermelonDBPackage())

override fun getJSIModulePackage(): JSIModulePackage {
return JSIModulePackage { reactApplicationContext, jsContext ->
mutableListOf<JSIModuleSpec<JSIModule>>().apply {
addAll(
WatermelonDBJSIPackage().getJSIModules(
reactApplicationContext,
jsContext,
),
)
}
}
}
listOf(MainReactPackage(), NativeModulesPackage(), WatermelonDBPackage(), WatermelonDBJSIPackage())

override fun getJSMainModuleName(): String = "src/index.integrationTests.native"
}
Expand Down
5 changes: 4 additions & 1 deletion src/adapters/sqlite/makeDispatcher/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type {
SqliteDispatcherOptions,
} from '../type'

const { WMDatabaseBridge } = NativeModules
const { WMDatabaseBridge, WMDatabaseJSIBridge } = NativeModules

class SqliteNativeModulesDispatcher implements SqliteDispatcher {
_tag: ConnectionTag
Expand Down Expand Up @@ -143,6 +143,9 @@ const initializeJSI = () => {
logger.error('[SQLite] Failed to initialize JSI')
logger.error(e)
}
} else if (WMDatabaseJSIBridge && WMDatabaseJSIBridge.install) {
WMDatabaseJSIBridge.install()
return !!global.nativeWatermelonCreateAdapter
}

return false
Expand Down
Loading