Skip to content

Commit

Permalink
Merge pull request #1854 from prathameshmm02/fix/jsi-compatibility
Browse files Browse the repository at this point in the history
Add jsi support for newer react native versions(old-arch)
  • Loading branch information
radex authored Nov 29, 2024
2 parents 70ef1df + 1e905f0 commit f5c34eb
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 118 deletions.
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

0 comments on commit f5c34eb

Please sign in to comment.