Skip to content

Commit

Permalink
feat: Use undefined as a default value (**BREAKING CHANGE**) (#306)
Browse files Browse the repository at this point in the history
* feat: Use `undefined` as a default value

* Update MmkvHostObject.cpp

* Use `hasValue` out parameter

* fix: Code style

* fix: Use MMKV 1.2.13

* fix: Update MMKV/ submodule
  • Loading branch information
mrousavy committed Mar 30, 2022
1 parent 26b1a78 commit 6cbee87
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 85 deletions.
135 changes: 79 additions & 56 deletions android/src/main/cpp/MmkvHostObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "MmkvHostObject.h"
#include <MMKV.h>
#include <android/log.h>
#include <string>

MmkvHostObject::MmkvHostObject(const std::string& instanceId, std::string path, std::string cryptKey) {
__android_log_print(ANDROID_LOG_INFO, "RNMMKV", "Creating MMKV instance \"%s\"... (Path: %s, Encryption-Key: %s)",
Expand Down Expand Up @@ -59,21 +60,23 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
const jsi::Value& thisValue,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
if (!arguments[0].isString()) throw jsi::JSError(runtime, "MMKV::set: First argument ('key') has to be of type string!");
auto keyName = arguments[0].getString(runtime).utf8(runtime);

if (arguments[1].isBool()) {
instance->set(arguments[1].getBool(), keyName);
} else if (arguments[1].isNumber()) {
instance->set(arguments[1].getNumber(), keyName);
} else if (arguments[1].isString()) {
auto stringValue = arguments[1].getString(runtime).utf8(runtime);
instance->set(stringValue, keyName);
} else {
throw jsi::JSError(runtime, "MMKV::set: 'value' argument is not of type bool, number or string!");
}
return jsi::Value::undefined();
});
if (!arguments[0].isString()) {
throw jsi::JSError(runtime, "MMKV::set: First argument ('key') has to be of type string!");
}

auto keyName = arguments[0].getString(runtime).utf8(runtime);
if (arguments[1].isBool()) {
instance->set(arguments[1].getBool(), keyName);
} else if (arguments[1].isNumber()) {
instance->set(arguments[1].getNumber(), keyName);
} else if (arguments[1].isString()) {
auto stringValue = arguments[1].getString(runtime).utf8(runtime);
instance->set(stringValue, keyName);
} else {
throw jsi::JSError(runtime, "MMKV::set: 'value' argument is not of type bool, number or string!");
}
return jsi::Value::undefined();
});
}

if (propName == "getBoolean") {
Expand All @@ -85,11 +88,19 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
const jsi::Value& thisValue,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
if (!arguments[0].isString()) throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
auto keyName = arguments[0].getString(runtime).utf8(runtime);
auto value = instance->getBool(keyName);
return jsi::Value(value);
});
if (!arguments[0].isString()) {
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
}

auto keyName = arguments[0].getString(runtime).utf8(runtime);
bool hasValue;
auto value = instance->getBool(keyName, false, &hasValue);
if (hasValue) {
return jsi::Value(value);
} else {
return jsi::Value::undefined();
}
});
}

if (propName == "getString") {
Expand All @@ -101,17 +112,19 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
const jsi::Value& thisValue,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
if (!arguments[0].isString()) throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");

auto keyName = arguments[0].getString(runtime).utf8(runtime);
if (!arguments[0].isString()) {
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
}

std::string result;
bool hasValue = instance->getString(keyName, result);
if (hasValue)
return jsi::Value(runtime, jsi::String::createFromUtf8(runtime, result));
else
return jsi::Value::undefined();
});
auto keyName = arguments[0].getString(runtime).utf8(runtime);
std::string result;
bool hasValue = instance->getString(keyName, result);
if (hasValue) {
return jsi::Value(runtime, jsi::String::createFromUtf8(runtime, result));
} else {
return jsi::Value::undefined();
}
});
}

if (propName == "getNumber") {
Expand All @@ -123,12 +136,19 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
const jsi::Value& thisValue,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
if (!arguments[0].isString()) throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
auto keyName = arguments[0].getString(runtime).utf8(runtime);
if (!arguments[0].isString()) {
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
}

auto value = instance->getDouble(keyName);
return jsi::Value(value);
});
auto keyName = arguments[0].getString(runtime).utf8(runtime);
bool hasValue;
auto value = instance->getDouble(keyName, 0.0, &hasValue);
if (hasValue) {
return jsi::Value(value);
} else {
return jsi::Value::undefined();
}
});
}

if (propName == "contains") {
Expand All @@ -140,12 +160,14 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
const jsi::Value& thisValue,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
if (!arguments[0].isString()) throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
auto keyName = arguments[0].getString(runtime).utf8(runtime);
if (!arguments[0].isString()) {
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
}

bool containsKey = instance->containsKey(keyName);
return jsi::Value(containsKey);
});
auto keyName = arguments[0].getString(runtime).utf8(runtime);
bool containsKey = instance->containsKey(keyName);
return jsi::Value(containsKey);
});
}

if (propName == "delete") {
Expand All @@ -157,12 +179,14 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
const jsi::Value& thisValue,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
if (!arguments[0].isString()) throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
auto keyName = arguments[0].getString(runtime).utf8(runtime);
if (!arguments[0].isString()) {
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
}

instance->removeValueForKey(keyName);
return jsi::Value::undefined();
});
auto keyName = arguments[0].getString(runtime).utf8(runtime);
instance->removeValueForKey(keyName);
return jsi::Value::undefined();
});
}

if (propName == "getAllKeys") {
Expand All @@ -174,13 +198,13 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
const jsi::Value& thisValue,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
auto keys = instance->allKeys();
auto array = jsi::Array(runtime, keys.size());
for (int i = 0; i < keys.size(); i++) {
array.setValueAtIndex(runtime, i, keys[i]);
}
return array;
});
auto keys = instance->allKeys();
auto array = jsi::Array(runtime, keys.size());
for (int i = 0; i < keys.size(); i++) {
array.setValueAtIndex(runtime, i, keys[i]);
}
return array;
});
}

if (propName == "clearAll") {
Expand All @@ -192,10 +216,9 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
const jsi::Value& thisValue,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
instance->clearAll();

return jsi::Value::undefined();
});
instance->clearAll();
return jsi::Value::undefined();
});
}

if (propName == "recrypt") {
Expand Down
16 changes: 8 additions & 8 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ PODS:
- ReactCommon/turbomodule/core (= 0.66.0)
- fmt (6.2.1)
- glog (0.3.5)
- MMKV (1.2.10):
- MMKVCore (~> 1.2.10)
- MMKVCore (1.2.10)
- MMKV (1.2.13):
- MMKVCore (~> 1.2.13)
- MMKVCore (1.2.13)
- RCT-Folly (2021.06.28.00-v2):
- boost
- DoubleConversion
Expand Down Expand Up @@ -213,7 +213,7 @@ PODS:
- React-logger (0.66.0):
- glog
- react-native-mmkv (2.2.0):
- MMKV
- MMKV (>= 1.2.13)
- React-Core
- React-perflogger (0.66.0)
- React-RCTActionSheet (0.66.0):
Expand Down Expand Up @@ -399,8 +399,8 @@ SPEC CHECKSUMS:
FBReactNativeSpec: 3b1e86618e902743fde35b40cf9ebd100fd655b7
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 5337263514dd6f09803962437687240c5dc39aa4
MMKV: 76033b9ace2006623308910a3afcc0e25eba3140
MMKVCore: b00e7a09ec77a1b916aef336eedd3b99ec249978
MMKV: aac95d817a100479445633f2b3ed8961b4ac5043
MMKVCore: 3388952ded307e41b3ed8a05892736a236ed1b8e
RCT-Folly: a21c126816d8025b547704b777a2ba552f3d9fa9
RCTRequired: e4a18a90004e0ed97bba9081099104fd0f658dc9
RCTTypeSafety: 8a3c31d38de58e1a6a7df6e4e643644a60b00e22
Expand All @@ -413,7 +413,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: 6a05173dc0142abc582bd4edd2d23146b8cc218a
React-jsinspector: be95ad424ba9f7b817aff22732eb9b1b810a000a
React-logger: 9a9cd87d4ea681ae929b32ef580638ff1b50fb24
react-native-mmkv: 2a15aadabf649c364cab7975eef52848611eea25
react-native-mmkv: b3fbff006ba573aa9244174166bbf18d8dc210a7
React-perflogger: 1f554c2b684e2f484f9edcdfdaeedab039fbaca8
React-RCTActionSheet: 610d5a5d71ab4808734782c8bca6a12ec3563672
React-RCTAnimation: ec6ed97370ace32724c253f29f0586cafcab8126
Expand All @@ -431,4 +431,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: ff9edaeddbabd71ed0391ba2617d0998f8c3e9ba

COCOAPODS: 1.10.2
COCOAPODS: 1.11.2
30 changes: 20 additions & 10 deletions ios/MmkvHostObject.mm
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,10 @@
const jsi::Value* arguments,
size_t count) -> jsi::Value {
if (!arguments[0].isString()) {
throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
throw jsi::JSError(runtime, "MMKV::set: First argument ('key') has to be of type string!");
}

auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));

auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
if (arguments[1].isBool()) {
[instance setBool:arguments[1].getBool() forKey:keyName];
} else if (arguments[1].isNumber()) {
Expand All @@ -82,7 +81,7 @@
} else {
throw jsi::JSError(runtime, "Second argument ('value') has to be of type bool, number or string!");
}

return jsi::Value::undefined();
});
}
Expand All @@ -101,8 +100,13 @@
}

auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
bool value = [instance getBoolForKey:keyName];
return jsi::Value(value);
bool hasValue;
auto value = [instance getBoolForKey:keyName defaultValue:false hasValue:&hasValue];
if (hasValue) {
return jsi::Value(value);
} else {
return jsi::Value::undefined();
}
});
}

Expand All @@ -121,10 +125,11 @@

auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
auto value = [instance getStringForKey:keyName];
if (value != nil)
if (value != nil) {
return convertNSStringToJSIString(runtime, value);
else
} else {
return jsi::Value::undefined();
}
});
}

Expand All @@ -142,8 +147,13 @@
}

auto keyName = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
auto value = [instance getDoubleForKey:keyName];
return jsi::Value(value);
bool hasValue;
auto value = [instance getDoubleForKey:keyName defaultValue:0.0 hasValue:&hasValue];
if (hasValue) {
return jsi::Value(value);
} else {
return jsi::Value::undefined();
}
});
}

Expand Down
2 changes: 1 addition & 1 deletion react-native-mmkv.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ Pod::Spec.new do |s|
'ios/**/*.h'
]

s.dependency "MMKV"
s.dependency "MMKV", ">= 1.2.13"
s.dependency "React-Core"
end
18 changes: 9 additions & 9 deletions src/MMKV.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,23 @@ interface MMKVInterface {
*/
set: (key: string, value: boolean | string | number) => void;
/**
* Get a boolean value for the given `key`.
* Get the boolean value for the given `key`, or `undefined` if it does not exist.
*
* @default false
* @default undefined
*/
getBoolean: (key: string) => boolean;
getBoolean: (key: string) => boolean | undefined;
/**
* Get a string value for the given `key`.
* Get the string value for the given `key`, or `undefined` if it does not exist.
*
* @default undefined
*/
getString: (key: string) => string | undefined;
/**
* Get a number value for the given `key`.
* Get the number value for the given `key`, or `undefined` if it does not exist.
*
* @default 0
* @default undefined
*/
getNumber: (key: string) => number;
getNumber: (key: string) => number | undefined;
/**
* Checks whether the given `key` is being stored in this MMKV instance.
*/
Expand Down Expand Up @@ -175,15 +175,15 @@ export class MMKV implements MMKVInterface {
const func = this.getFunctionFromCache('set');
return func(key, value);
}
getBoolean(key: string): boolean {
getBoolean(key: string): boolean | undefined {
const func = this.getFunctionFromCache('getBoolean');
return func(key);
}
getString(key: string): string | undefined {
const func = this.getFunctionFromCache('getString');
return func(key);
}
getNumber(key: string): number {
getNumber(key: string): number | undefined {
const func = this.getFunctionFromCache('getNumber');
return func(key);
}
Expand Down
2 changes: 1 addition & 1 deletion src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function useMMKV(configuration?: MMKVConfiguration): MMKV {
}

function createMMKVHook<
T extends boolean | number | (string | undefined),
T extends (boolean | number | string) | undefined,
TSet extends T | undefined,
TSetAction extends TSet | ((current: T) => TSet)
>(getter: (instance: MMKV, key: string) => T) {
Expand Down

0 comments on commit 6cbee87

Please sign in to comment.