From 3a08e1ccabb9556ef1ffc4203427af986b3718c9 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Tue, 14 Feb 2023 15:46:42 +0100 Subject: [PATCH] Fix a bug in parsing client reset configuration (#5288) * Fix a bug in parsing client reset configuration * Add default callbacks for recoverOrDiscard mode --- CHANGELOG.md | 2 ++ lib/extensions.js | 3 +++ src/js_sync.hpp | 26 ++++++++++++++------------ types/index.d.ts | 4 ++-- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 881a0e9433..40ad4e9beb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,11 +9,13 @@ ### Enhancements * Converting flexible sync Realms to bundled and local realms is now supported. ([realm/realm-core#6076](https://github.com/realm/realm-core/pull/6076)) +* For client reset mode `onRecoveryOrDiscard`, the `onDiscard` and `onRecovery` callbacks now have simple default values. ([#5288](https://github.com/realm/realm-js/pull/5288), since v11.1.0) ### Fixed * Fixed possible segfault in sync client where async callback was using object after being deallocated. ([realm/realm-core#6053](https://github.com/realm/realm-core/issues/6053), since v10.11.0) * Fixed crash when using client reset with recovery and flexible sync with a single subscription ([#6070](https://github.com/realm/realm-core/issues/6070), since v10.19.5) * If `path` is defined in the configuration, it will used for synced Realms too. Relative paths will be appended to a default prefix (prefix is computed using app id and user id). Absolute paths are left untouched. (since v10.0.0) +* Fixed a bug related to parsing the client reset configuration. ([#5288](https://github.com/realm/realm-js/pull/5288), since v11.1.0) ### Compatibility * React Native >= v0.70.0 diff --git a/lib/extensions.js b/lib/extensions.js index e581822b16..999ccecdc1 100644 --- a/lib/extensions.js +++ b/lib/extensions.js @@ -61,6 +61,8 @@ module.exports = function (realmConstructor) { realmConstructor._UUID = realmConstructor.BSON.UUID; const { DefaultNetworkTransport } = require("@realm/network-transport"); realmConstructor._networkTransport = new DefaultNetworkTransport(); + realmConstructor._defaultOnDiscardCallback = () => {}; + realmConstructor._defaultOnRecoveryCallback = () => {}; // Adds to cache when serializing an object for toJSON const addToCache = (cache, realmObj, value) => { @@ -488,6 +490,7 @@ module.exports = function (realmConstructor) { realmConstructor.ClientResetMode = { Manual: "manual", + DiscardLocal: "discardLocal", DiscardUnsyncedChanges: "discardUnsyncedChanges", RecoverUnsyncedChanges: "recoverUnsyncedChanges", RecoverOrDiscardUnsyncedChanges: "recoverOrDiscardUnsyncedChanges", diff --git a/src/js_sync.hpp b/src/js_sync.hpp index 03b15ad7ae..89bf0a7d22 100644 --- a/src/js_sync.hpp +++ b/src/js_sync.hpp @@ -1303,21 +1303,23 @@ void SyncClass::populate_sync_config(ContextType ctx, ObjectType realm_constr } case realm::ClientResyncMode::RecoverOrDiscard: { - ValueType client_reset_after_value = Object::get_property(ctx, client_reset_object, "onDiscard"); - if (Value::is_undefined(ctx, client_reset_after_value)) { - throw std::invalid_argument("'onDiscard' is required"); - } - - ValueType client_reset_recovery_value = - Object::get_property(ctx, client_reset_object, "onRecovery"); - if (Value::is_undefined(ctx, client_reset_after_value)) { - throw std::invalid_argument("'onRecovery' is required"); - } + auto get_callback = [=](std::string callback_name, std::string default_callback_name) { + ValueType callback_value = Object::get_property(ctx, client_reset_object, callback_name); + if (Value::is_undefined(ctx, callback_value)) { + auto realm = Value::validated_to_object(ctx, Object::get_global(ctx, "Realm")); + auto default_callback_value = Value::validated_to_object( + ctx, Object::get_property(ctx, realm, default_callback_name)); + return Value::validated_to_function(ctx, default_callback_value); + } + else { + return Value::validated_to_function(ctx, callback_value); + } + }; FunctionType client_reset_discard_callback = - Value::validated_to_function(ctx, client_reset_after_value); + get_callback("onDiscard", "_defaultOnDiscardCallback"); FunctionType client_reset_recovery_callback = - Value::validated_to_function(ctx, client_reset_recovery_value); + get_callback("onRecovery", "_defaultOnRecoveryCallback"); auto client_reset_after_handler = util::EventLoopDispatcher( diff --git a/types/index.d.ts b/types/index.d.ts index 1ff43e28f8..5ac56ae8b8 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -175,8 +175,8 @@ declare namespace Realm { interface ClientResetRecoveryOrDiscardConfiguration { mode: ClientResetMode.RecoverOrDiscardUnsyncedChanges; onBefore?: ClientResetBeforeCallback; - onRecovery: ClientResetAfterCallback; - onDiscard: ClientResetAfterCallback; + onRecovery?: ClientResetAfterCallback; + onDiscard?: ClientResetAfterCallback; onFallback?: ClientResetFallbackCallback; }