diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h --- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h +++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h @@ -34,6 +34,9 @@ jsi::Value removeAllDrafts(jsi::Runtime &rt) override; jsi::Value getAllMessages(jsi::Runtime &rt) override; jsi::Array getAllMessagesSync(jsi::Runtime &rt) override; + jsi::Value processDraftStoreOperations( + jsi::Runtime &rt, + const jsi::Array &operations) override; jsi::Value processMessageStoreOperations( jsi::Runtime &rt, const jsi::Array &operations) override; diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp --- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp +++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp @@ -1,6 +1,7 @@ #include "CommCoreModule.h" #include "../CryptoTools/DeviceID.h" #include "DatabaseManager.h" +#include "DraftStoreOperations.h" #include "GRPCStreamHostObject.h" #include "InternalModules/GlobalDBSingleton.h" #include "InternalModules/GlobalNetworkSingleton.h" @@ -313,11 +314,83 @@ }); } -#define REKEY_OPERATION "rekey" -#define REMOVE_OPERATION "remove" -#define REPLACE_OPERATION "replace" -#define REMOVE_MSGS_FOR_THREADS_OPERATION "remove_messages_for_threads" -#define REMOVE_ALL_OPERATION "remove_all" +const std::string UPDATE_DRAFT_OPERATION = "update"; +const std::string MOVE_DRAFT_OPERATION = "move"; +const std::string REMOVE_ALL_DRAFTS_OPERATION = "remove_all"; + +std::vector> +createDraftStoreOperations(jsi::Runtime &rt, const jsi::Array &operations) { + std::vector> draftStoreOps; + for (auto idx = 0; idx < operations.size(rt); idx++) { + auto op = operations.getValueAtIndex(rt, idx).asObject(rt); + auto op_type = op.getProperty(rt, "type").asString(rt).utf8(rt); + auto payload_obj = op.getProperty(rt, "payload").asObject(rt); + if (op_type == UPDATE_DRAFT_OPERATION) { + draftStoreOps.push_back( + std::make_unique(rt, payload_obj)); + } else if (op_type == MOVE_DRAFT_OPERATION) { + draftStoreOps.push_back( + std::make_unique(rt, payload_obj)); + } else if (op_type == REMOVE_ALL_DRAFTS_OPERATION) { + draftStoreOps.push_back(std::make_unique()); + } else { + throw std::runtime_error("unsupported operation: " + op_type); + } + } + return draftStoreOps; +} + +jsi::Value CommCoreModule::processDraftStoreOperations( + jsi::Runtime &rt, + const jsi::Array &operations) { + std::string createOperationsError; + std::shared_ptr>> + draftStoreOpsPtr; + try { + auto draftStoreOps = createDraftStoreOperations(rt, operations); + draftStoreOpsPtr = + std::make_shared>>( + std::move(draftStoreOps)); + } catch (std::runtime_error &e) { + createOperationsError = e.what(); + } + + return createPromiseAsJSIValue( + rt, [=](jsi::Runtime &innerRt, std::shared_ptr promise) { + taskType job = [=]() { + std::string error = createOperationsError; + + if (!error.size()) { + try { + DatabaseManager::getQueryExecutor().beginTransaction(); + for (const auto &operation : *draftStoreOpsPtr) { + operation->execute(); + } + DatabaseManager::getQueryExecutor().commitTransaction(); + } catch (std::system_error &e) { + error = e.what(); + DatabaseManager::getQueryExecutor().rollbackTransaction(); + } + } + + this->jsInvoker_->invokeAsync([=]() { + if (error.size()) { + promise->reject(error); + } else { + promise->resolve(jsi::Value::undefined()); + } + }); + }; + GlobalDBSingleton::instance.scheduleOrRun(job); + }); +} + +const std::string REKEY_OPERATION = "rekey"; +const std::string REMOVE_OPERATION = "remove"; +const std::string REPLACE_OPERATION = "replace"; +const std::string REMOVE_MSGS_FOR_THREADS_OPERATION = + "remove_messages_for_threads"; +const std::string REMOVE_ALL_OPERATION = "remove_all"; std::vector> createMessageStoreOperations(jsi::Runtime &rt, const jsi::Array &operations) { diff --git a/native/cpp/CommonCpp/_generated/NativeModules.h b/native/cpp/CommonCpp/_generated/NativeModules.h --- a/native/cpp/CommonCpp/_generated/NativeModules.h +++ b/native/cpp/CommonCpp/_generated/NativeModules.h @@ -25,6 +25,7 @@ virtual jsi::Value removeAllDrafts(jsi::Runtime &rt) = 0; virtual jsi::Value getAllMessages(jsi::Runtime &rt) = 0; virtual jsi::Array getAllMessagesSync(jsi::Runtime &rt) = 0; +virtual jsi::Value processDraftStoreOperations(jsi::Runtime &rt, const jsi::Array &operations) = 0; virtual jsi::Value processMessageStoreOperations(jsi::Runtime &rt, const jsi::Array &operations) = 0; virtual void processMessageStoreOperationsSync(jsi::Runtime &rt, const jsi::Array &operations) = 0; virtual jsi::Value getAllThreads(jsi::Runtime &rt) = 0; diff --git a/native/cpp/CommonCpp/_generated/NativeModules.cpp b/native/cpp/CommonCpp/_generated/NativeModules.cpp --- a/native/cpp/CommonCpp/_generated/NativeModules.cpp +++ b/native/cpp/CommonCpp/_generated/NativeModules.cpp @@ -33,6 +33,9 @@ static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getAllMessagesSync(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { return static_cast(&turboModule)->getAllMessagesSync(rt); } +static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processDraftStoreOperations(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->processDraftStoreOperations(rt, args[0].getObject(rt).getArray(rt)); +} static jsi::Value __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processMessageStoreOperations(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { return static_cast(&turboModule)->processMessageStoreOperations(rt, args[0].getObject(rt).getArray(rt)); } @@ -99,6 +102,7 @@ methodMap_["removeAllDrafts"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_removeAllDrafts}; methodMap_["getAllMessages"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getAllMessages}; methodMap_["getAllMessagesSync"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getAllMessagesSync}; + methodMap_["processDraftStoreOperations"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processDraftStoreOperations}; methodMap_["processMessageStoreOperations"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processMessageStoreOperations}; methodMap_["processMessageStoreOperationsSync"] = MethodMetadata {1, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_processMessageStoreOperationsSync}; methodMap_["getAllThreads"] = MethodMetadata {0, __hostFunction_CommCoreModuleSchemaCxxSpecJSI_getAllThreads}; diff --git a/native/schema/CommCoreModuleSchema.js b/native/schema/CommCoreModuleSchema.js --- a/native/schema/CommCoreModuleSchema.js +++ b/native/schema/CommCoreModuleSchema.js @@ -5,6 +5,7 @@ import { TurboModuleRegistry } from 'react-native'; import type { TurboModule } from 'react-native/Libraries/TurboModule/RCTExport'; +import type { ClientDBDraftStoreOperation } from 'lib/types/draft-types'; import type { ClientDBMessageInfo, ClientDBMessageStoreOperation, @@ -27,6 +28,9 @@ +removeAllDrafts: () => Promise; +getAllMessages: () => Promise<$ReadOnlyArray>; +getAllMessagesSync: () => $ReadOnlyArray; + +processDraftStoreOperations: ( + operations: $ReadOnlyArray, + ) => Promise; +processMessageStoreOperations: ( operations: $ReadOnlyArray, ) => Promise;