react-native-mmkv 1.6.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,13 +37,13 @@
37
37
  ## Sponsors
38
38
 
39
39
  <div align="right">
40
- <a href="https://getstream.io/chat/react-native-chat/tutorial/?utm_source=github&utm_medium=github_repo_content_ad&utm_content=developer&utm_campaign=github_sept2021_reactnativechat">
40
+ <a href="https://getstream.io/chat/react-native-chat/tutorial/?utm_source=Github&utm_medium=Github_Repo_Content_Ad&utm_content=Developer&utm_campaign=Github_Jan2022_ReactNative&utm_term=react-native-mmkv">
41
41
  <img align="right" src="https://theme.zdassets.com/theme_assets/9442057/efc3820e436f9150bc8cf34267fff4df052a1f9c.png" height="40" />
42
42
  </a>
43
43
  </div>
44
44
 
45
45
  react-native-mmkv is sponsored by **getstream.io**. <br/>
46
- [Try the React Native Chat tutorial 💬](https://getstream.io/chat/react-native-chat/tutorial/?utm_source=github&utm_medium=github_repo_content_ad&utm_content=developer&utm_campaign=github_sept2021_reactnativechat)
46
+ [Try the React Native Chat tutorial 💬](https://getstream.io/chat/react-native-chat/tutorial/?utm_source=Github&utm_medium=Github_Repo_Content_Ad&utm_content=Developer&utm_campaign=Github_Jan2022_ReactNative&utm_term=react-native-mmkv)
47
47
 
48
48
  ## Benchmark
49
49
 
@@ -57,25 +57,19 @@ react-native-mmkv is sponsored by **getstream.io**. <br/>
57
57
 
58
58
  ## Installation
59
59
 
60
- ```sh
61
- npm install react-native-mmkv
62
- ```
63
-
64
- ### iOS
65
-
66
- iOS installation is automatic, just run:
60
+ ### React Native
67
61
 
68
62
  ```sh
63
+ yarn add react-native-mmkv
69
64
  cd ios && pod install
70
65
  ```
71
66
 
72
- ### Android
73
-
74
- To correctly initialize MMKV on Android, please follow the [Installation guide](./INSTALL.md).
75
-
76
67
  ### Expo
77
68
 
78
- See this comment for more information: [mrousavy/react-native-mmkv#157 (comment)](https://github.com/mrousavy/react-native-mmkv/issues/157#issuecomment-960647481).
69
+ ```sh
70
+ expo install react-native-mmkv
71
+ expo prebuild
72
+ ```
79
73
 
80
74
  ## Usage
81
75
 
@@ -168,6 +162,7 @@ const userObject = JSON.parse(jsonUser)
168
162
  * [Migrate from AsyncStorage](./docs/MIGRATE_FROM_ASYNC_STORAGE.md)
169
163
  * [Using MMKV with redux-persis](./docs/WRAPPER_REDUX.md)
170
164
  * [Using MMKV with mobx-persist-storage](./docs/WRAPPER_MOBX.md)
165
+ * [Using MMKV with mobx-persist](./docs/WRAPPER_MOBXPERSIST.md)
171
166
 
172
167
  ## Limitations
173
168
 
@@ -17,10 +17,6 @@ if(${REACT_NATIVE_VERSION} LESS 66)
17
17
  INCLUDE_JSI_CPP
18
18
  "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/jsi.cpp"
19
19
  )
20
- set (
21
- INCLUDE_JSIDYNAMIC_CPP
22
- "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/JSIDynamic.cpp"
23
- )
24
20
  endif()
25
21
 
26
22
  add_library(reactnativemmkv # <-- Library name
@@ -28,7 +24,6 @@ add_library(reactnativemmkv # <-- Library name
28
24
  src/main/cpp/cpp-adapter.cpp
29
25
  src/main/cpp/MmkvHostObject.cpp
30
26
  ${INCLUDE_JSI_CPP} # only on older RN versions
31
- ${INCLUDE_JSIDYNAMIC_CPP} # only on older RN versions
32
27
  )
33
28
 
34
29
  set_target_properties(
@@ -38,7 +33,7 @@ set_target_properties(
38
33
  POSITION_INDEPENDENT_CODE ON
39
34
  )
40
35
 
41
- file (GLOB LIBRN_DIR "${BUILD_DIR}/react-native-0*/jni/${ANDROID_ABI}")
36
+ file (GLOB LIBRN_DIR "${PREBUILT_DIR}/${ANDROID_ABI}")
42
37
 
43
38
  find_library(
44
39
  log-lib
@@ -2,6 +2,24 @@ import groovy.json.JsonSlurper
2
2
  import org.apache.tools.ant.filters.ReplaceTokens
3
3
  import java.nio.file.Paths
4
4
 
5
+ static def findNodeModules(baseDir) {
6
+ def basePath = baseDir.toPath().normalize()
7
+ // Node's module resolution algorithm searches up to the root directory,
8
+ // after which the base path will be null
9
+ while (basePath) {
10
+ def nodeModulesPath = Paths.get(basePath.toString(), "node_modules")
11
+ def reactNativePath = Paths.get(nodeModulesPath.toString(), "react-native")
12
+ if (nodeModulesPath.toFile().exists() && reactNativePath.toFile().exists()) {
13
+ return nodeModulesPath.toString()
14
+ }
15
+ basePath = basePath.getParent()
16
+ }
17
+ throw new GradleException("MMKV: Failed to find node_modules/ path!")
18
+ }
19
+
20
+ def nodeModules = findNodeModules(projectDir)
21
+ logger.warn("MMKV: node_modules/ found at: ${nodeModules}")
22
+
5
23
  buildscript {
6
24
  repositories {
7
25
  google()
@@ -28,7 +46,12 @@ def getExtOrIntegerDefault(name) {
28
46
  return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['Mmkv_' + name]).toInteger()
29
47
  }
30
48
 
31
- def found = false
49
+ def reactNativeArchitectures() {
50
+ def value = project.getProperties().get("reactNativeArchitectures")
51
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
52
+ }
53
+
54
+ def sourceBuild = false
32
55
  def defaultDir = null
33
56
  def androidSourcesDir = null
34
57
  def androidSourcesName = 'React Native sources'
@@ -36,45 +59,28 @@ def androidSourcesName = 'React Native sources'
36
59
  if (rootProject.ext.has('reactNativeAndroidRoot')) {
37
60
  defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
38
61
  androidSourcesDir = defaultDir.parentFile.toString()
62
+ } else if (findProject(':ReactAndroid') != null) {
63
+ sourceBuild = true
64
+ defaultDir = project(':ReactAndroid').projectDir
65
+ androidSourcesDir = defaultDir.parentFile.toString()
39
66
  } else {
40
- defaultDir = new File(
41
- projectDir,
42
- '/../../../node_modules/react-native/android'
43
- )
67
+ defaultDir = file("$nodeModules/react-native/android")
44
68
  androidSourcesDir = defaultDir.parentFile.toString()
45
69
  }
46
70
 
47
- if (defaultDir.exists()) {
48
- found = true
49
- } else {
50
- def parentDir = rootProject.projectDir
51
- defaultDir = new File(parentDir, '../node_modules/react-native/android')
52
-
53
- 1.upto(5, {
54
- if (found) return true
55
- parentDir = parentDir.parentFile
56
-
57
- androidSourcesDir = new File(
58
- parentDir,
59
- 'node_modules/react-native'
60
- )
61
-
62
- def androidPrebuiltBinaryDir = new File(
63
- parentDir,
64
- 'node_modules/react-native/android'
71
+ if (!defaultDir.exists()) {
72
+ throw new GradleException(
73
+ "${project.name}: React Native android directory (node_modules/react-native/android) does not exist! Resolved node_modules to: ${nodeModules}"
65
74
  )
66
-
67
- if (androidPrebuiltBinaryDir.exists()) {
68
- found = true
69
- } else if (androidSourcesDir.exists()) {
70
- found = true
71
- }
72
- })
73
75
  }
74
76
 
77
+ def prebuiltDir = sourceBuild
78
+ ? "$nodeModules/react-native/ReactAndroid/src/main/jni/prebuilt/lib"
79
+ : "$buildDir/react-native-0*/jni"
80
+
75
81
 
76
82
  def reactProperties = new Properties()
77
- file("$projectDir/../node_modules/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
83
+ file("$nodeModules/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
78
84
  def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger()
79
85
 
80
86
  android {
@@ -90,12 +96,15 @@ android {
90
96
  externalNativeBuild {
91
97
  cmake {
92
98
  cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
93
- abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
94
99
  arguments '-DANDROID_STL=c++_shared',
95
100
  "-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
96
- "-DNODE_MODULES_DIR=${defaultDir.parentFile.parentFile.toString()}"
101
+ "-DNODE_MODULES_DIR=${nodeModules}",
102
+ "-DPREBUILT_DIR=${prebuiltDir}"
97
103
  }
98
104
  }
105
+ ndk {
106
+ abiFilters (*reactNativeArchitectures())
107
+ }
99
108
  }
100
109
 
101
110
  dexOptions {
@@ -135,41 +144,9 @@ repositories {
135
144
  mavenCentral()
136
145
  google()
137
146
 
138
- if (defaultDir.exists()) {
139
- maven {
140
- url defaultDir.toString()
141
- name androidSourcesName
142
- }
143
-
144
- logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
145
- } else {
146
- def parentDir = rootProject.projectDir
147
- defaultDir = new File(parentDir, '../node_modules/react-native/android')
148
-
149
- 1.upto(5, {
150
- if (androidPrebuiltBinaryDir.exists()) {
151
- maven {
152
- url androidPrebuiltBinaryDir.toString()
153
- name androidSourcesName
154
- }
155
-
156
- logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
157
- } else if (androidSourcesDir.exists()) {
158
- maven {
159
- url androidSourcesDir.toString()
160
- name androidSourcesName
161
- }
162
-
163
- logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
164
- }
165
- })
166
- }
167
-
168
- if (!found) {
169
- throw new GradleException(
170
- "${project.name}: unable to locate React Native android sources. " +
171
- "Ensure you have you installed React Native as a dependency in your project and try again."
172
- )
147
+ maven {
148
+ url defaultDir.toString()
149
+ name androidSourcesName
173
150
  }
174
151
  }
175
152
 
@@ -182,8 +159,10 @@ dependencies {
182
159
  //noinspection GradleDynamicVersion
183
160
  extractJNI("com.facebook.fbjni:fbjni:+")
184
161
 
185
- def rnAAR = fileTree("${defaultDir.toString()}").matching({ it.include "**/**/*.aar" }).singleFile
186
- extractJNI(files(rnAAR))
162
+ if (!sourceBuild) {
163
+ def rnAAR = fileTree("${defaultDir.toString()}").matching({ it.include "**/**/*.aar" }).singleFile
164
+ extractJNI(files(rnAAR))
165
+ }
187
166
  }
188
167
 
189
168
  // third-party-ndk deps headers
@@ -352,10 +331,22 @@ task extractJNIFiles {
352
331
  }
353
332
  extractJNIFiles.mustRunAfter extractAARHeaders
354
333
 
355
- tasks.whenTaskAdded { task ->
356
- if (!task.name.contains('Clean') && (task.name.contains('externalNative') || task.name.contains('CMake'))) {
357
- task.dependsOn(extractAARHeaders)
358
- task.dependsOn(extractJNIFiles)
359
- task.dependsOn(prepareThirdPartyNdkHeaders)
334
+ def nativeBuildDependsOn(dependsOnTask, variant) {
335
+ def buildTasks = tasks.findAll({ task ->
336
+ !task.name.contains("Clean") && (task.name.contains("externalNative") || task.name.contains("CMake")) })
337
+ if (variant != null) {
338
+ buildTasks = buildTasks.findAll({ task -> task.name.contains(variant) })
339
+ }
340
+ buildTasks.forEach { task -> task.dependsOn(dependsOnTask) }
341
+ }
342
+
343
+ afterEvaluate {
344
+ if (sourceBuild) {
345
+ nativeBuildDependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck", "Debug")
346
+ nativeBuildDependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck", "Rel")
347
+ } else {
348
+ nativeBuildDependsOn(extractAARHeaders, null)
349
+ nativeBuildDependsOn(extractJNIFiles, null)
350
+ nativeBuildDependsOn(prepareThirdPartyNdkHeaders, null)
360
351
  }
361
352
  }
@@ -1,24 +1,49 @@
1
1
  package com.reactnativemmkv;
2
2
 
3
+ import android.util.Log;
4
+
3
5
  import androidx.annotation.NonNull;
6
+ import androidx.annotation.Nullable;
4
7
 
5
8
  import com.facebook.react.bridge.JavaScriptContextHolder;
6
9
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
10
+ import com.facebook.react.bridge.ReactApplicationContext;
11
+ import com.facebook.react.bridge.ReactMethod;
12
+ import com.facebook.react.module.annotations.ReactModule;
7
13
 
14
+ @ReactModule(name = MmkvModule.NAME)
8
15
  public class MmkvModule extends ReactContextBaseJavaModule {
9
- static {
10
- System.loadLibrary("reactnativemmkv");
11
- }
16
+ public static final String NAME = "MMKV";
12
17
 
13
- private static native void nativeInstall(long jsiPtr, String path);
14
-
15
- public static void install(JavaScriptContextHolder jsContext, String storageDirectory) {
16
- nativeInstall(jsContext.get(), storageDirectory);
18
+ public MmkvModule(ReactApplicationContext reactContext) {
19
+ super(reactContext);
17
20
  }
18
21
 
19
22
  @NonNull
20
23
  @Override
21
24
  public String getName() {
22
- return "MMKV";
25
+ return NAME;
23
26
  }
27
+
28
+ @ReactMethod(isBlockingSynchronousMethod = true)
29
+ public boolean install(@Nullable String rootDirectory) {
30
+ try {
31
+ Log.i(NAME, "Loading C++ library...");
32
+ System.loadLibrary("reactnativemmkv");
33
+
34
+ JavaScriptContextHolder jsContext = getReactApplicationContext().getJavaScriptContextHolder();
35
+ if (rootDirectory == null) {
36
+ rootDirectory = getReactApplicationContext().getFilesDir().getAbsolutePath() + "/mmkv";
37
+ }
38
+ Log.i(NAME, "Installing MMKV JSI Bindings for MMKV root directory: " + rootDirectory);
39
+ nativeInstall(jsContext.get(), rootDirectory);
40
+ Log.i(NAME, "Successfully installed MMKV JSI Bindings!");
41
+ return true;
42
+ } catch (Exception exception) {
43
+ Log.e(NAME, "Failed to install MMKV JSI Bindings!", exception);
44
+ return false;
45
+ }
46
+ }
47
+
48
+ private static native void nativeInstall(long jsiPtr, String path);
24
49
  }
@@ -15,8 +15,7 @@ public class MmkvPackage implements ReactPackage {
15
15
  @NonNull
16
16
  @Override
17
17
  public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
18
- // TODO: Remove this dummy init, once TurboModules are stable I will migrate to those.
19
- return Collections.singletonList(new MmkvModule());
18
+ return Collections.singletonList(new MmkvModule(reactContext));
20
19
  }
21
20
 
22
21
  @NonNull
@@ -1,6 +1,6 @@
1
1
  #import <React/RCTBridgeModule.h>
2
2
 
3
- @interface Mmkv : NSObject <RCTBridgeModule>
3
+ @interface MmkvModule : NSObject <RCTBridgeModule>
4
4
 
5
5
  @property (nonatomic, assign) BOOL setBridgeOnMainQueue;
6
6
 
@@ -0,0 +1,70 @@
1
+ #import "MmkvModule.h"
2
+ #import "JSIUtils.h"
3
+
4
+ #import <React/RCTBridge+Private.h>
5
+ #import <React/RCTUtils.h>
6
+ #import <jsi/jsi.h>
7
+
8
+ #import <MMKV/MMKV.h>
9
+ #import "MmkvHostObject.h"
10
+
11
+ using namespace facebook;
12
+
13
+ @implementation MmkvModule
14
+ @synthesize bridge = _bridge;
15
+ @synthesize methodQueue = _methodQueue;
16
+
17
+ RCT_EXPORT_MODULE(MMKV)
18
+
19
+ + (NSString*)getPropertyAsStringOrNilFromObject:(jsi::Object&)object propertyName:(std::string)propertyName runtime:(jsi::Runtime&)runtime {
20
+ jsi::Value value = object.getProperty(runtime, propertyName.c_str());
21
+ std::string string = value.isString() ? value.asString(runtime).utf8(runtime) : "";
22
+ return string.length() > 0 ? [NSString stringWithUTF8String:string.c_str()] : nil;
23
+ }
24
+
25
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install:(nullable NSString*)storageDirectory)
26
+ {
27
+ NSLog(@"Installing global.mmkvCreateNewInstance...");
28
+ RCTBridge* bridge = [RCTBridge currentBridge];
29
+ RCTCxxBridge* cxxBridge = (RCTCxxBridge*)bridge;
30
+ if (cxxBridge == nil) {
31
+ return @false;
32
+ }
33
+
34
+ using namespace facebook;
35
+
36
+ auto jsiRuntime = (jsi::Runtime*) cxxBridge.runtime;
37
+ if (jsiRuntime == nil) {
38
+ return @false;
39
+ }
40
+ auto& runtime = *jsiRuntime;
41
+
42
+ [MMKV initializeMMKV:storageDirectory];
43
+
44
+ // MMKV.createNewInstance()
45
+ auto mmkvCreateNewInstance = jsi::Function::createFromHostFunction(runtime,
46
+ jsi::PropNameID::forAscii(runtime, "mmkvCreateNewInstance"),
47
+ 1,
48
+ [](jsi::Runtime& runtime,
49
+ const jsi::Value& thisValue,
50
+ const jsi::Value* arguments,
51
+ size_t count) -> jsi::Value {
52
+ if (count != 1) {
53
+ throw jsi::JSError(runtime, "MMKV.createNewInstance(..) expects one argument (object)!");
54
+ }
55
+ jsi::Object config = arguments[0].asObject(runtime);
56
+
57
+ NSString* instanceId = [MmkvModule getPropertyAsStringOrNilFromObject:config propertyName:"id" runtime:runtime];
58
+ NSString* path = [MmkvModule getPropertyAsStringOrNilFromObject:config propertyName:"path" runtime:runtime];
59
+ NSString* encryptionKey = [MmkvModule getPropertyAsStringOrNilFromObject:config propertyName:"encryptionKey" runtime:runtime];
60
+
61
+ auto instance = std::make_shared<MmkvHostObject>(instanceId, path, encryptionKey);
62
+ return jsi::Object::createFromHostObject(runtime, instance);
63
+ });
64
+ runtime.global().setProperty(runtime, "mmkvCreateNewInstance", std::move(mmkvCreateNewInstance));
65
+
66
+ NSLog(@"Installed global.mmkvCreateNewInstance!");
67
+ return @true;
68
+ }
69
+
70
+ @end
@@ -5,10 +5,22 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.createMMKV = void 0;
7
7
 
8
- // global func declaration for JSI functions
8
+ var _reactNative = require("react-native");
9
+
10
+ // Root directory of all MMKV stores
11
+ const ROOT_DIRECTORY = null;
12
+
9
13
  const createMMKV = config => {
14
+ // Check if the constructor exists. If not, try installing the JSI bindings.
10
15
  if (global.mmkvCreateNewInstance == null) {
11
- throw new Error('Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!');
16
+ // get the MMKV ReactModule
17
+ const MMKVModule = _reactNative.NativeModules.MMKV;
18
+ if (MMKVModule == null || typeof MMKVModule.install !== 'function') throw new Error('The native MMKV Module could not be found! Is it correctly installed and autolinked?'); // Call the synchronous blocking install() function
19
+
20
+ const result = MMKVModule.install(ROOT_DIRECTORY);
21
+ if (result !== true) throw new Error(`The native MMKV Module could not be installed! Looks like something went wrong when installing JSI bindings: ${result}`); // Check again if the constructor now exists. If not, throw an error.
22
+
23
+ if (global.mmkvCreateNewInstance == null) throw new Error('Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!');
12
24
  }
13
25
 
14
26
  return global.mmkvCreateNewInstance(config);
@@ -1 +1 @@
1
- {"version":3,"sources":["createMMKV.ts"],"names":["createMMKV","config","global","mmkvCreateNewInstance","Error"],"mappings":";;;;;;;AAEA;AAKO,MAAMA,UAAU,GAAIC,MAAD,IAA2C;AACnE,MAAIC,MAAM,CAACC,qBAAP,IAAgC,IAApC,EAA0C;AACxC,UAAM,IAAIC,KAAJ,CACJ,0MADI,CAAN;AAGD;;AAED,SAAOF,MAAM,CAACC,qBAAP,CAA6BF,MAA7B,CAAP;AACD,CARM","sourcesContent":["import type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';\n\n// global func declaration for JSI functions\ndeclare global {\n function mmkvCreateNewInstance(configuration: MMKVConfiguration): NativeMMKV;\n}\n\nexport const createMMKV = (config: MMKVConfiguration): NativeMMKV => {\n if (global.mmkvCreateNewInstance == null) {\n throw new Error(\n 'Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!'\n );\n }\n\n return global.mmkvCreateNewInstance(config);\n};\n"]}
1
+ {"version":3,"sources":["createMMKV.ts"],"names":["ROOT_DIRECTORY","createMMKV","config","global","mmkvCreateNewInstance","MMKVModule","NativeModules","MMKV","install","Error","result"],"mappings":";;;;;;;AAAA;;AAQA;AACA,MAAMA,cAA6B,GAAG,IAAtC;;AAEO,MAAMC,UAAU,GAAIC,MAAD,IAA2C;AACnE;AACA,MAAIC,MAAM,CAACC,qBAAP,IAAgC,IAApC,EAA0C;AACxC;AACA,UAAMC,UAAU,GAAGC,2BAAcC,IAAjC;AACA,QAAIF,UAAU,IAAI,IAAd,IAAsB,OAAOA,UAAU,CAACG,OAAlB,KAA8B,UAAxD,EACE,MAAM,IAAIC,KAAJ,CACJ,sFADI,CAAN,CAJsC,CAOxC;;AACA,UAAMC,MAAM,GAAGL,UAAU,CAACG,OAAX,CAAmBR,cAAnB,CAAf;AACA,QAAIU,MAAM,KAAK,IAAf,EACE,MAAM,IAAID,KAAJ,CACH,gHAA+GC,MAAO,EADnH,CAAN,CAVsC,CAaxC;;AACA,QAAIP,MAAM,CAACC,qBAAP,IAAgC,IAApC,EACE,MAAM,IAAIK,KAAJ,CACJ,0MADI,CAAN;AAGH;;AAED,SAAON,MAAM,CAACC,qBAAP,CAA6BF,MAA7B,CAAP;AACD,CAvBM","sourcesContent":["import { NativeModules } from 'react-native';\nimport type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';\n\n// global func declaration for JSI functions\ndeclare global {\n function mmkvCreateNewInstance(configuration: MMKVConfiguration): NativeMMKV;\n}\n\n// Root directory of all MMKV stores\nconst ROOT_DIRECTORY: string | null = null;\n\nexport const createMMKV = (config: MMKVConfiguration): NativeMMKV => {\n // Check if the constructor exists. If not, try installing the JSI bindings.\n if (global.mmkvCreateNewInstance == null) {\n // get the MMKV ReactModule\n const MMKVModule = NativeModules.MMKV;\n if (MMKVModule == null || typeof MMKVModule.install !== 'function')\n throw new Error(\n 'The native MMKV Module could not be found! Is it correctly installed and autolinked?'\n );\n // Call the synchronous blocking install() function\n const result = MMKVModule.install(ROOT_DIRECTORY);\n if (result !== true)\n throw new Error(\n `The native MMKV Module could not be installed! Looks like something went wrong when installing JSI bindings: ${result}`\n );\n // Check again if the constructor now exists. If not, throw an error.\n if (global.mmkvCreateNewInstance == null)\n throw new Error(\n 'Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!'\n );\n }\n\n return global.mmkvCreateNewInstance(config);\n};\n"]}
@@ -1,7 +1,17 @@
1
- // global func declaration for JSI functions
1
+ import { NativeModules } from 'react-native';
2
+ // Root directory of all MMKV stores
3
+ const ROOT_DIRECTORY = null;
2
4
  export const createMMKV = config => {
5
+ // Check if the constructor exists. If not, try installing the JSI bindings.
3
6
  if (global.mmkvCreateNewInstance == null) {
4
- throw new Error('Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!');
7
+ // get the MMKV ReactModule
8
+ const MMKVModule = NativeModules.MMKV;
9
+ if (MMKVModule == null || typeof MMKVModule.install !== 'function') throw new Error('The native MMKV Module could not be found! Is it correctly installed and autolinked?'); // Call the synchronous blocking install() function
10
+
11
+ const result = MMKVModule.install(ROOT_DIRECTORY);
12
+ if (result !== true) throw new Error(`The native MMKV Module could not be installed! Looks like something went wrong when installing JSI bindings: ${result}`); // Check again if the constructor now exists. If not, throw an error.
13
+
14
+ if (global.mmkvCreateNewInstance == null) throw new Error('Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!');
5
15
  }
6
16
 
7
17
  return global.mmkvCreateNewInstance(config);
@@ -1 +1 @@
1
- {"version":3,"sources":["createMMKV.ts"],"names":["createMMKV","config","global","mmkvCreateNewInstance","Error"],"mappings":"AAEA;AAKA,OAAO,MAAMA,UAAU,GAAIC,MAAD,IAA2C;AACnE,MAAIC,MAAM,CAACC,qBAAP,IAAgC,IAApC,EAA0C;AACxC,UAAM,IAAIC,KAAJ,CACJ,0MADI,CAAN;AAGD;;AAED,SAAOF,MAAM,CAACC,qBAAP,CAA6BF,MAA7B,CAAP;AACD,CARM","sourcesContent":["import type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';\n\n// global func declaration for JSI functions\ndeclare global {\n function mmkvCreateNewInstance(configuration: MMKVConfiguration): NativeMMKV;\n}\n\nexport const createMMKV = (config: MMKVConfiguration): NativeMMKV => {\n if (global.mmkvCreateNewInstance == null) {\n throw new Error(\n 'Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!'\n );\n }\n\n return global.mmkvCreateNewInstance(config);\n};\n"]}
1
+ {"version":3,"sources":["createMMKV.ts"],"names":["NativeModules","ROOT_DIRECTORY","createMMKV","config","global","mmkvCreateNewInstance","MMKVModule","MMKV","install","Error","result"],"mappings":"AAAA,SAASA,aAAT,QAA8B,cAA9B;AAQA;AACA,MAAMC,cAA6B,GAAG,IAAtC;AAEA,OAAO,MAAMC,UAAU,GAAIC,MAAD,IAA2C;AACnE;AACA,MAAIC,MAAM,CAACC,qBAAP,IAAgC,IAApC,EAA0C;AACxC;AACA,UAAMC,UAAU,GAAGN,aAAa,CAACO,IAAjC;AACA,QAAID,UAAU,IAAI,IAAd,IAAsB,OAAOA,UAAU,CAACE,OAAlB,KAA8B,UAAxD,EACE,MAAM,IAAIC,KAAJ,CACJ,sFADI,CAAN,CAJsC,CAOxC;;AACA,UAAMC,MAAM,GAAGJ,UAAU,CAACE,OAAX,CAAmBP,cAAnB,CAAf;AACA,QAAIS,MAAM,KAAK,IAAf,EACE,MAAM,IAAID,KAAJ,CACH,gHAA+GC,MAAO,EADnH,CAAN,CAVsC,CAaxC;;AACA,QAAIN,MAAM,CAACC,qBAAP,IAAgC,IAApC,EACE,MAAM,IAAII,KAAJ,CACJ,0MADI,CAAN;AAGH;;AAED,SAAOL,MAAM,CAACC,qBAAP,CAA6BF,MAA7B,CAAP;AACD,CAvBM","sourcesContent":["import { NativeModules } from 'react-native';\nimport type { MMKVConfiguration, NativeMMKV } from 'react-native-mmkv';\n\n// global func declaration for JSI functions\ndeclare global {\n function mmkvCreateNewInstance(configuration: MMKVConfiguration): NativeMMKV;\n}\n\n// Root directory of all MMKV stores\nconst ROOT_DIRECTORY: string | null = null;\n\nexport const createMMKV = (config: MMKVConfiguration): NativeMMKV => {\n // Check if the constructor exists. If not, try installing the JSI bindings.\n if (global.mmkvCreateNewInstance == null) {\n // get the MMKV ReactModule\n const MMKVModule = NativeModules.MMKV;\n if (MMKVModule == null || typeof MMKVModule.install !== 'function')\n throw new Error(\n 'The native MMKV Module could not be found! Is it correctly installed and autolinked?'\n );\n // Call the synchronous blocking install() function\n const result = MMKVModule.install(ROOT_DIRECTORY);\n if (result !== true)\n throw new Error(\n `The native MMKV Module could not be installed! Looks like something went wrong when installing JSI bindings: ${result}`\n );\n // Check again if the constructor now exists. If not, throw an error.\n if (global.mmkvCreateNewInstance == null)\n throw new Error(\n 'Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!'\n );\n }\n\n return global.mmkvCreateNewInstance(config);\n};\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-mmkv",
3
- "version": "1.6.0",
4
- "description": "An efficient, small mobile key-value storage framework developed by WeChat. Works on Android and iOS.",
3
+ "version": "2.0.0",
4
+ "description": "The fastest key/value storage for React Native. ~30x faster than AsyncStorage! Works on Android, iOS and Web.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
7
7
  "types": "lib/typescript/index.d.ts",
@@ -28,7 +28,8 @@
28
28
  "typescript": "tsc --noEmit",
29
29
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
30
30
  "lint-ci": "yarn lint -f ./node_modules/@firmnav/eslint-github-actions-formatter/dist/formatter.js",
31
- "build": "git submodule update --init --recursive && bob build",
31
+ "prepare": "git submodule update --init --recursive",
32
+ "build": "bob build",
32
33
  "update-submodule": "git submodule update --remote --merge",
33
34
  "release": "release-it",
34
35
  "example": "yarn --cwd example",
@@ -17,7 +17,7 @@ Pod::Spec.new do |s|
17
17
  # Note how this does not include headers, since those can nameclash.
18
18
  s.source_files = [
19
19
  "ios/**/*.{m,mm}",
20
- "ios/Mmkv.h"
20
+ "ios/MmkvModule.h"
21
21
  ]
22
22
  # Any private headers that are not globally unique should be mentioned here.
23
23
  # Otherwise there will be a nameclash, since CocoaPods flattens out any header directories
@@ -1,16 +0,0 @@
1
- package com.reactnativemmkv;
2
-
3
- import com.facebook.react.bridge.JSIModulePackage;
4
- import com.facebook.react.bridge.JSIModuleSpec;
5
- import com.facebook.react.bridge.JavaScriptContextHolder;
6
- import com.facebook.react.bridge.ReactApplicationContext;
7
- import java.util.Collections;
8
- import java.util.List;
9
-
10
- public class MmkvModulePackage implements JSIModulePackage {
11
- @Override
12
- public List<JSIModuleSpec> getJSIModules(ReactApplicationContext reactApplicationContext, JavaScriptContextHolder jsContext) {
13
- MmkvModule.install(jsContext, reactApplicationContext.getFilesDir().getAbsolutePath() + "/mmkv");
14
- return Collections.emptyList();
15
- }
16
- }
package/ios/Mmkv.mm DELETED
@@ -1,76 +0,0 @@
1
- #import "Mmkv.h"
2
- #import "JSIUtils.h"
3
-
4
- #import <React/RCTBridge+Private.h>
5
- #import <React/RCTUtils.h>
6
- #import <jsi/jsi.h>
7
-
8
- #import <MMKV/MMKV.h>
9
- #import "MmkvHostObject.h"
10
-
11
- using namespace facebook;
12
-
13
- @implementation Mmkv
14
- @synthesize bridge = _bridge;
15
- @synthesize methodQueue = _methodQueue;
16
-
17
- RCT_EXPORT_MODULE()
18
-
19
- + (BOOL)requiresMainQueueSetup {
20
- return YES;
21
- }
22
-
23
- static void install(jsi::Runtime & jsiRuntime)
24
- {
25
- // MMKV.createNewInstance()
26
- auto mmkvCreateNewInstance = jsi::Function::createFromHostFunction(jsiRuntime,
27
- jsi::PropNameID::forAscii(jsiRuntime, "mmkvCreateNewInstance"),
28
- 1,
29
- [](jsi::Runtime& runtime,
30
- const jsi::Value& thisValue,
31
- const jsi::Value* arguments,
32
- size_t count) -> jsi::Value {
33
- if (count != 1) {
34
- throw jsi::JSError(runtime, "MMKV.createNewInstance(..) expects one argument (object)!");
35
- }
36
- jsi::Object config = arguments[0].asObject(runtime);
37
-
38
- NSString* instanceId = [Mmkv getPropertyAsStringOrNilFromObject:config propertyName:"id" runtime:runtime];
39
- NSString* path = [Mmkv getPropertyAsStringOrNilFromObject:config propertyName:"path" runtime:runtime];
40
- NSString* encryptionKey = [Mmkv getPropertyAsStringOrNilFromObject:config propertyName:"encryptionKey" runtime:runtime];
41
-
42
- auto instance = std::make_shared<MmkvHostObject>(instanceId, path, encryptionKey);
43
- return jsi::Object::createFromHostObject(runtime, instance);
44
- });
45
- jsiRuntime.global().setProperty(jsiRuntime, "mmkvCreateNewInstance", std::move(mmkvCreateNewInstance));
46
- }
47
-
48
- + (NSString*)getPropertyAsStringOrNilFromObject:(jsi::Object&)object propertyName:(std::string)propertyName runtime:(jsi::Runtime&)runtime {
49
- jsi::Value value = object.getProperty(runtime, propertyName.c_str());
50
- std::string string = value.isString() ? value.asString(runtime).utf8(runtime) : "";
51
- return string.length() > 0 ? [NSString stringWithUTF8String:string.c_str()] : nil;
52
- }
53
-
54
- - (void)setup
55
- {
56
- RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
57
- if (!cxxBridge.runtime) {
58
- // retry 10ms later - THIS IS A WACK WORKAROUND. wait for TurboModules to land.
59
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.001 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
60
- [self setup];
61
- });
62
- return;
63
- }
64
-
65
- [MMKV initializeMMKV:nil];
66
- install(*(jsi::Runtime *)cxxBridge.runtime);
67
- }
68
-
69
- - (void)setBridge:(RCTBridge *)bridge
70
- {
71
- _bridge = bridge;
72
- _setBridgeOnMainQueue = RCTIsMainQueue();
73
- [self setup];
74
- }
75
-
76
- @end