Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
1f4f616
newArch2
Nov 23, 2025
cfad2bf
Merge branch 'newArch2'
Nov 23, 2025
8909194
fix: migration form /prisma/migrations by default
Nov 24, 2025
28e3245
fix: capture prisma async state by value
Mar 14, 2026
cd52410
Add synchronous React Native reads
Jun 27, 2026
d151d08
重构 React Native Prisma 7 为同步驱动架构并移除旧原生引擎,支持 Expo SQLite 同步 CRUD 与事务回滚
Aug 25, 2026
75a5fea
升级开发基线到 Expo 58 canary,移除 fork 内 Expo 57 依赖树并对齐主工程运行环境
Aug 25, 2026
cc8788e
补齐 Prisma 7 在 React Native JSC 下的运行时兼容与幂等安装修补,移除 Node 内置模块依赖并自动准备同步查询客户端
Aug 25, 2026
69d4c3b
精简同步专用 API 命名并明确 Prisma 客户端准备脚本职责
Aug 25, 2026
45c2728
完善 Prisma 7.9 中文文档与可复现发布构建,统一客户端准备脚本并加入轻量混淆产物
Aug 25, 2026
1fc2fa6
精简 Prisma 7.9 工程配置并移除无原生模块后的无效自动链接声明
Aug 25, 2026
120e29f
新增 Prisma 7.9 SQLite 原生查询编译器并通过 Expo Modules 提供同步 iOS JSI 能力
Aug 25, 2026
2090949
接入 Hermes 原生 Query Compiler 并移除生成客户端运行时的 WebAssembly 依赖
Aug 25, 2026
f3805ce
更新中文文档说明 Hermes 同步架构与 release 预编译二进制交付方式
Aug 25, 2026
6310399
补齐 x86_64 模拟器预编译切片以支持通用 iOS Simulator Release 链接
Aug 25, 2026
fc6ced5
支持 PrismaClient 在设备端自动应用迁移并保持后续查询同步返回
Aug 25, 2026
04147a9
精简 React Native Prisma 公开入口与无用类型依赖,统一根包导入方式
Aug 25, 2026
c281704
更新中文文档说明迁移生成、设备应用流程与精简后的数据库用法
Aug 25, 2026
9e5f0bc
修正 Expo Canary 的 peer 版本范围以消除预发布依赖警告
Aug 25, 2026
cf3077c
兼容 Expo 58 Canary 的 SemVer 预发布匹配规则
Aug 25, 2026
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
12 changes: 11 additions & 1 deletion android/src/main/java/com/prisma/PrismaModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,17 @@ public void createDir(File dir) throws IOException
public void install() {
ReactApplicationContext context = this.getReactApplicationContext();
long jsContextPointer = context.getJavaScriptContextHolder().get();
CallInvokerHolderImpl jsCallInvokerHolder = (CallInvokerHolderImpl)context.getCatalystInstance().getJSCallInvokerHolder();
if (jsContextPointer == 0) {
throw new RuntimeException("JSI runtime pointer is null. Make sure Hermes is enabled and the runtime is initialized before calling install().");
}
CallInvokerHolderImpl jsCallInvokerHolder;
if (context.getJSCallInvokerHolder() != null) {
jsCallInvokerHolder = (CallInvokerHolderImpl) context.getJSCallInvokerHolder();
} else if (context.getCatalystInstance() != null) {
jsCallInvokerHolder = (CallInvokerHolderImpl) context.getCatalystInstance().getJSCallInvokerHolder();
} else {
throw new RuntimeException("JSCallInvokerHolder is not available yet.");
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
String dbPath = context.getDatabasePath("defaultDatabase").getAbsolutePath().replace("defaultDatabase", "");
String migrationsPath;
try {
Expand Down
3 changes: 1 addition & 2 deletions copy-migrations.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ echo "Copying prisma migration files..."
MIGRATIONS_TARGET=${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}

rm -rf "$MIGRATIONS_TARGET/migrations"
mkdir "$MIGRATIONS_TARGET/migrations"
cp -r ${SRCROOT}/../migrations ${MIGRATIONS_TARGET}
cp -r ${SRCROOT}/../prisma/migrations "${MIGRATIONS_TARGET}/migrations"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

echo "migration files copied ✅"
7 changes: 6 additions & 1 deletion cpp/QueryEngineHostObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
#ifndef query_engine_host_object_h
#define query_engine_host_object_h

#include "query_engine.h"
#include <TargetConditionals.h>
#if TARGET_OS_SIMULATOR
#include "../engines/ios/QueryEngine.xcframework/ios-arm64_x86_64-simulator/Headers/query_engine.h"
#else
#include "../engines/ios/QueryEngine.xcframework/ios-arm64/Headers/query_engine.h"
#endif
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
#include <jsi/jsi.h>
#include <memory>
#include <string>
Expand Down
4 changes: 2 additions & 2 deletions cpp/react-native-prisma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void install_cxx(jsi::Runtime &rt,
}

auto log_callback_fn = [&rt, js_log_callback](std::string msg) {
call_invoker->invokeAsync([&rt, msg, &js_log_callback] {
call_invoker->invokeAsync([&rt, msg, js_log_callback] {
js_log_callback->asObject(rt).asFunction(rt).call(
rt, jsi::String::createFromUtf8(rt, msg));
});
Expand Down Expand Up @@ -130,7 +130,7 @@ void install_cxx(jsi::Runtime &rt,
auto resolve = std::make_shared<jsi::Value>(rt, args[0]);
auto reject = std::make_shared<jsi::Value>(rt, args[1]);

auto task = [&rt, &queryEngineHostObject, body = std::move(body),
auto task = [&rt, queryEngineHostObject, body = std::move(body),
trace = std::move(trace), tx_id = std::move(tx_id), resolve,
reject]() {
const char *response;
Expand Down
115 changes: 91 additions & 24 deletions ios/Prisma.mm
Original file line number Diff line number Diff line change
@@ -1,52 +1,119 @@
#import "Prisma.h"
#import <jsi/jsi.h>
#import <React/RCTBridge.h>
#import <React/RCTBridge+Private.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <dispatch/dispatch.h>
#import <ReactCommon/RCTTurboModule.h>
#import <UIKit/UIKit.h>
#import <iostream>

#ifdef RCT_NEW_ARCH_ENABLED
#import "RNPrismaSpecJSI.h"
#endif

// Forward declare runtimeExecutor to silence selector warnings on older headers
@interface RCTBridge (RuntimeExecutorForwardDecl)
- (facebook::react::RuntimeExecutor)runtimeExecutor;
@end

static NSString *PrismaLibraryPath() {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, true);
return [paths objectAtIndex:0];
}

static NSString *PrismaMigrationsPath() {
auto bundleURL = NSBundle.mainBundle.bundleURL;
auto migrations_path_absolute = [NSString stringWithFormat:@"%@%@", bundleURL.absoluteString, @"migrations"];
return [migrations_path_absolute stringByReplacingOccurrencesOfString:@"file://" withString:@""];
}

static inline void InstallInRuntime(facebook::jsi::Runtime &runtime,
std::shared_ptr<facebook::react::CallInvoker> callInvoker) {
NSString *libraryPath = PrismaLibraryPath();
NSString *migrationsPath = PrismaMigrationsPath();
prisma::install_cxx(runtime, callInvoker, [libraryPath UTF8String], [migrationsPath UTF8String]);
}

static RCTBridge *ResolveBridge(id<RCTBridgeModule> module) {
RCTBridge *bridge = nil;
if ([module respondsToSelector:@selector(bridge)]) {
bridge = ((id<RCTBridgeModule>)module).bridge;
}
if (bridge == nil) {
bridge = [RCTBridge currentBridge];
}
return bridge;
}

@implementation Prisma

@synthesize bridge=_bridge;

RCT_EXPORT_MODULE()

// Old-arch sync install for classic bridge
#if !RCT_NEW_ARCH_ENABLED
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
{
RCTCxxBridge *cxxBridge = (RCTCxxBridge *)_bridge;
if (cxxBridge == nil) {
return @false;
#if DEBUG
std::cout << "▲ NSHomeDirectory:\n" << [NSHomeDirectory() UTF8String] << std::endl;
std::cout << "▲ Library Path:\n" << [PrismaLibraryPath() UTF8String] << std::endl;
std::cout << "▲ Migrations Path:\n" << [PrismaMigrationsPath() UTF8String] << std::endl;
#endif

BOOL ok = NO;
auto okPtr = &ok;
RCTBridge *bridge = ResolveBridge(self);

// Try new-arch path first if runtimeExecutor is available
if (bridge && [bridge respondsToSelector:@selector(runtimeExecutor)]) {
facebook::react::RuntimeExecutor executor = RCTRuntimeExecutorFromBridge(bridge);
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
executor([&](facebook::jsi::Runtime &runtime) {
InstallInRuntime(runtime, bridge.jsCallInvoker);
*okPtr = YES;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
return @(ok);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

auto jsiRuntime = (facebook::jsi::Runtime *)cxxBridge.runtime;
if (jsiRuntime == nil) {

// Fallback to old-arch bridge access
RCTBridge *legacyBridge = _bridge ?: bridge;
RCTCxxBridge *cxxBridge = (RCTCxxBridge *)legacyBridge;
if (cxxBridge == nil || cxxBridge.runtime == nil) {
NSLog(@"[Prisma] no runtime available to install cxx");
return @false;
}

auto jsiRuntime = (facebook::jsi::Runtime *)cxxBridge.runtime;
auto &runtime = *jsiRuntime;
auto callInvoker = _bridge.jsCallInvoker;

// get migrations folder
auto bundleURL = NSBundle.mainBundle.bundleURL;
auto migrations_path_absolute = [NSString stringWithFormat:@"%@%@", bundleURL.absoluteString, @"migrations"];
auto migrations_path = [migrations_path_absolute stringByReplacingOccurrencesOfString:@"file://" withString:@""];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, true);
NSString *libraryPath = [paths objectAtIndex:0];

#if DEBUG
std::cout << "▲ NSHomeDirectory:\n" << [NSHomeDirectory() UTF8String] << std::endl;
std::cout << "▲ Library Path:\n" << [libraryPath UTF8String] << std::endl;
std::cout << "▲ Migrations Path:\n" << [migrations_path UTF8String] << std::endl;
#endif
auto callInvoker = _bridge ? _bridge.jsCallInvoker : legacyBridge.jsCallInvoker;

prisma::install_cxx(runtime, callInvoker, [libraryPath UTF8String], [migrations_path UTF8String]);
return nil;
InstallInRuntime(runtime, callInvoker);
return @true;
}
#else
// Required by NativePrismaSpec protocol in new-arch; TurboModule path uses C++ spec below.
- (void)install {}
#endif

#ifdef RCT_NEW_ARCH_ENABLED
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<facebook::react::NativePrismaSpecJSI>(params);
class PrismaCxxTurboModule final : public facebook::react::NativePrismaCxxSpec<PrismaCxxTurboModule> {
public:
explicit PrismaCxxTurboModule(std::shared_ptr<facebook::react::CallInvoker> jsInvoker)
: NativePrismaCxxSpec(std::move(jsInvoker)) {}

void install(facebook::jsi::Runtime &rt) {
InstallInRuntime(rt, this->jsInvoker_);
}
};

return std::make_shared<PrismaCxxTurboModule>(params.jsInvoker);
}
#endif

Expand Down