react-native-mmkv-dz 2.5.1
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/LICENSE +219 -0
- package/MMKV/CHANGELOG.md +553 -0
- package/MMKV/Core/CMakeLists.txt +153 -0
- package/MMKV/Core/CodedInputData.cpp +228 -0
- package/MMKV/Core/CodedInputData.h +83 -0
- package/MMKV/Core/CodedInputDataCrypt.cpp +280 -0
- package/MMKV/Core/CodedInputDataCrypt.h +87 -0
- package/MMKV/Core/CodedInputDataCrypt_OSX.cpp +62 -0
- package/MMKV/Core/CodedInputData_OSX.cpp +92 -0
- package/MMKV/Core/CodedOutputData.cpp +174 -0
- package/MMKV/Core/CodedOutputData.h +82 -0
- package/MMKV/Core/Core.xcodeproj/project.pbxproj +702 -0
- package/MMKV/Core/Core.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/MMKV/Core/Core.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/Core.xcscheme +67 -0
- package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/MMKVWatchCore.xcscheme +67 -0
- package/MMKV/Core/InterProcessLock.cpp +186 -0
- package/MMKV/Core/InterProcessLock.h +119 -0
- package/MMKV/Core/InterProcessLock_Android.cpp +103 -0
- package/MMKV/Core/InterProcessLock_Win32.cpp +108 -0
- package/MMKV/Core/KeyValueHolder.cpp +236 -0
- package/MMKV/Core/KeyValueHolder.h +118 -0
- package/MMKV/Core/MMBuffer.cpp +185 -0
- package/MMKV/Core/MMBuffer.h +107 -0
- package/MMKV/Core/MMKV.cpp +1418 -0
- package/MMKV/Core/MMKV.h +386 -0
- package/MMKV/Core/MMKVLog.cpp +127 -0
- package/MMKV/Core/MMKVLog.h +86 -0
- package/MMKV/Core/MMKVLog_Android.cpp +79 -0
- package/MMKV/Core/MMKVMetaInfo.hpp +81 -0
- package/MMKV/Core/MMKVPredef.h +245 -0
- package/MMKV/Core/MMKV_Android.cpp +259 -0
- package/MMKV/Core/MMKV_IO.cpp +1119 -0
- package/MMKV/Core/MMKV_IO.h +57 -0
- package/MMKV/Core/MMKV_OSX.cpp +347 -0
- package/MMKV/Core/MMKV_OSX.h +51 -0
- package/MMKV/Core/MemoryFile.cpp +537 -0
- package/MMKV/Core/MemoryFile.h +182 -0
- package/MMKV/Core/MemoryFile_Android.cpp +211 -0
- package/MMKV/Core/MemoryFile_Linux.cpp +120 -0
- package/MMKV/Core/MemoryFile_OSX.cpp +142 -0
- package/MMKV/Core/MemoryFile_Win32.cpp +536 -0
- package/MMKV/Core/MiniPBCoder.cpp +366 -0
- package/MMKV/Core/MiniPBCoder.h +129 -0
- package/MMKV/Core/MiniPBCoder_OSX.cpp +228 -0
- package/MMKV/Core/PBEncodeItem.hpp +86 -0
- package/MMKV/Core/PBUtility.cpp +61 -0
- package/MMKV/Core/PBUtility.h +153 -0
- package/MMKV/Core/ScopedLock.hpp +69 -0
- package/MMKV/Core/ThreadLock.cpp +68 -0
- package/MMKV/Core/ThreadLock.h +78 -0
- package/MMKV/Core/ThreadLock_Win32.cpp +89 -0
- package/MMKV/Core/aes/AESCrypt.cpp +256 -0
- package/MMKV/Core/aes/AESCrypt.h +107 -0
- package/MMKV/Core/aes/openssl/openssl_aes-armv4.S +1231 -0
- package/MMKV/Core/aes/openssl/openssl_aes.h +118 -0
- package/MMKV/Core/aes/openssl/openssl_aes_core.cpp +1044 -0
- package/MMKV/Core/aes/openssl/openssl_aes_locl.h +38 -0
- package/MMKV/Core/aes/openssl/openssl_aesv8-armx.S +308 -0
- package/MMKV/Core/aes/openssl/openssl_arm_arch.h +84 -0
- package/MMKV/Core/aes/openssl/openssl_cfb128.cpp +97 -0
- package/MMKV/Core/aes/openssl/openssl_md32_common.h +254 -0
- package/MMKV/Core/aes/openssl/openssl_md5.h +49 -0
- package/MMKV/Core/aes/openssl/openssl_md5_dgst.cpp +166 -0
- package/MMKV/Core/aes/openssl/openssl_md5_locl.h +75 -0
- package/MMKV/Core/aes/openssl/openssl_md5_one.cpp +30 -0
- package/MMKV/Core/aes/openssl/openssl_opensslconf.h +271 -0
- package/MMKV/Core/core.vcxproj +186 -0
- package/MMKV/Core/core.vcxproj.filters +150 -0
- package/MMKV/Core/crc32/Checksum.h +67 -0
- package/MMKV/Core/crc32/crc32_armv8.cpp +132 -0
- package/MMKV/Core/crc32/zlib/crc32.cpp +55 -0
- package/MMKV/Core/crc32/zlib/crc32.h +48 -0
- package/MMKV/Core/crc32/zlib/zconf.h +380 -0
- package/MMKV/Core/crc32/zlib/zutil.h +25 -0
- package/MMKV/LICENSE.TXT +193 -0
- package/MMKV/README.md +288 -0
- package/README.md +221 -0
- package/android/CMakeLists.txt +71 -0
- package/android/build.gradle +371 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/cpp/MmkvHostObject.cpp +302 -0
- package/android/src/main/cpp/MmkvHostObject.h +26 -0
- package/android/src/main/cpp/cpp-adapter.cpp +65 -0
- package/android/src/main/java/com/reactnativemmkv/MmkvModule.java +49 -0
- package/android/src/main/java/com/reactnativemmkv/MmkvPackage.java +26 -0
- package/cpp/TypedArray.cpp +341 -0
- package/cpp/TypedArray.h +175 -0
- package/ios/JSIUtils.h +50 -0
- package/ios/JSIUtils.mm +194 -0
- package/ios/Mmkv.xcodeproj/project.pbxproj +291 -0
- package/ios/MmkvHostObject.h +27 -0
- package/ios/MmkvHostObject.mm +299 -0
- package/ios/MmkvModule.h +5 -0
- package/ios/MmkvModule.mm +73 -0
- package/lib/commonjs/MMKV.js +146 -0
- package/lib/commonjs/MMKV.js.map +1 -0
- package/lib/commonjs/PlatformChecker.js +16 -0
- package/lib/commonjs/PlatformChecker.js.map +1 -0
- package/lib/commonjs/createMMKV.js +66 -0
- package/lib/commonjs/createMMKV.js.map +1 -0
- package/lib/commonjs/createMMKV.mock.js +40 -0
- package/lib/commonjs/createMMKV.mock.js.map +1 -0
- package/lib/commonjs/createMMKV.web.js +77 -0
- package/lib/commonjs/createMMKV.web.js.map +1 -0
- package/lib/commonjs/createTextEncoder.js +24 -0
- package/lib/commonjs/createTextEncoder.js.map +1 -0
- package/lib/commonjs/hooks.js +200 -0
- package/lib/commonjs/hooks.js.map +1 -0
- package/lib/commonjs/index.js +32 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/module/MMKV.js +134 -0
- package/lib/module/MMKV.js.map +1 -0
- package/lib/module/PlatformChecker.js +9 -0
- package/lib/module/PlatformChecker.js.map +1 -0
- package/lib/module/createMMKV.js +55 -0
- package/lib/module/createMMKV.js.map +1 -0
- package/lib/module/createMMKV.mock.js +31 -0
- package/lib/module/createMMKV.mock.js.map +1 -0
- package/lib/module/createMMKV.web.js +67 -0
- package/lib/module/createMMKV.web.js.map +1 -0
- package/lib/module/createTextEncoder.js +17 -0
- package/lib/module/createTextEncoder.js.map +1 -0
- package/lib/module/hooks.js +181 -0
- package/lib/module/hooks.js.map +1 -0
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -0
- package/lib/typescript/MMKV.d.ts +137 -0
- package/lib/typescript/PlatformChecker.d.ts +1 -0
- package/lib/typescript/createMMKV.d.ts +6 -0
- package/lib/typescript/createMMKV.mock.d.ts +2 -0
- package/lib/typescript/createMMKV.web.d.ts +2 -0
- package/lib/typescript/createTextEncoder.d.ts +1 -0
- package/lib/typescript/hooks.d.ts +81 -0
- package/lib/typescript/index.d.ts +2 -0
- package/package.json +168 -0
- package/react-native-mmkv.podspec +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
<a href="https://margelo.io">
|
|
2
|
+
<img src="./img/banner.svg" width="100%" />
|
|
3
|
+
</a>
|
|
4
|
+
|
|
5
|
+
<div align="center">
|
|
6
|
+
<h1 align="center">MMKV</h1>
|
|
7
|
+
<h3 align="center">The fastest key/value storage for React Native.</h3>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div align="center">
|
|
11
|
+
<a align="center" href="https://github.com/mrousavy?tab=followers">
|
|
12
|
+
<img src="https://img.shields.io/github/followers/mrousavy?label=Follow%20%40mrousavy&style=social" />
|
|
13
|
+
</a>
|
|
14
|
+
<br/>
|
|
15
|
+
<a align="center" href="https://twitter.com/mrousavy">
|
|
16
|
+
<img src="https://img.shields.io/twitter/follow/mrousavy?label=Follow%20%40mrousavy&style=social" />
|
|
17
|
+
</a>
|
|
18
|
+
<br />
|
|
19
|
+
<a href="https://github.com/sponsors/mrousavy">
|
|
20
|
+
<img align="right" width="160" alt="This library helped you? Consider sponsoring!" src=".github/funding-octocat.svg">
|
|
21
|
+
</a>
|
|
22
|
+
</div>
|
|
23
|
+
<br/>
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
* **MMKV** is an efficient, small mobile key-value storage framework developed by WeChat. See [Tencent/MMKV](https://github.com/Tencent/MMKV) for more information
|
|
27
|
+
* **react-native-mmkv** is a library that allows you to easily use **MMKV** inside your React Native applications. It provides fast and direct bindings to the native C++ library which are accessible through a simple JS API.
|
|
28
|
+
|
|
29
|
+
## Features
|
|
30
|
+
|
|
31
|
+
* **Get** and **set** strings, booleans and numbers
|
|
32
|
+
* **Fully synchronous** calls, no async/await, no Promises, no Bridge.
|
|
33
|
+
* **Encryption** support (secure storage)
|
|
34
|
+
* **Multiple instances** support (separate user-data with global data)
|
|
35
|
+
* **Customize storage location**
|
|
36
|
+
* **High performance** because everything is **written in C++**
|
|
37
|
+
* **~30x faster than AsyncStorage**
|
|
38
|
+
* Uses [**JSI**](https://github.com/react-native-community/discussions-and-proposals/issues/91) instead of the "old" Bridge
|
|
39
|
+
* **iOS**, **Android** and **Web** support
|
|
40
|
+
* Easy to use **React Hooks** API
|
|
41
|
+
|
|
42
|
+
## Sponsors
|
|
43
|
+
|
|
44
|
+
<div align="right">
|
|
45
|
+
<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">
|
|
46
|
+
<img align="right" src="https://theme.zdassets.com/theme_assets/9442057/efc3820e436f9150bc8cf34267fff4df052a1f9c.png" height="40" />
|
|
47
|
+
</a>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
react-native-mmkv is sponsored by **getstream.io**. <br/>
|
|
51
|
+
[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)
|
|
52
|
+
|
|
53
|
+
## Benchmark
|
|
54
|
+
|
|
55
|
+
[StorageBenchmark](https://github.com/mrousavy/StorageBenchmark) compares popular storage libraries against each other by reading a value from storage for 1000 times:
|
|
56
|
+
|
|
57
|
+
<div align="center">
|
|
58
|
+
<a href="https://github.com/mrousavy/StorageBenchmark">
|
|
59
|
+
<img src="./img/benchmark_1000_get.png" />
|
|
60
|
+
</a>
|
|
61
|
+
<p>
|
|
62
|
+
<b>MMKV vs other storage libraries</b>: Reading a value from Storage 1000 times. <br/>
|
|
63
|
+
Measured in milliseconds on an iPhone 11 Pro, lower is better. <br/>
|
|
64
|
+
</p>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
69
|
+
### React Native
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
yarn add react-native-mmkv
|
|
73
|
+
cd ios && pod install
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Expo
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
expo install react-native-mmkv
|
|
80
|
+
expo prebuild
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Usage
|
|
84
|
+
|
|
85
|
+
### Create a new instance
|
|
86
|
+
|
|
87
|
+
To create a new instance of the MMKV storage, use the `MMKV` constructor. It is recommended that you re-use this instance throughout your entire app instead of creating a new instance each time, so `export` the `storage` object.
|
|
88
|
+
|
|
89
|
+
#### Default
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
import { MMKV } from 'react-native-mmkv'
|
|
93
|
+
|
|
94
|
+
export const storage = new MMKV()
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This creates a new storage instance using the default MMKV storage ID (`mmkv.default`).
|
|
98
|
+
|
|
99
|
+
#### Customize
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
import { MMKV } from 'react-native-mmkv'
|
|
103
|
+
|
|
104
|
+
export const storage = new MMKV({
|
|
105
|
+
id: `user-${userId}-storage`,
|
|
106
|
+
path: `${USER_DIRECTORY}/storage`,
|
|
107
|
+
encryptionKey: 'hunter2'
|
|
108
|
+
})
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This creates a new storage instance using a custom MMKV storage ID. By using a custom storage ID, your storage is separated from the default MMKV storage of your app.
|
|
112
|
+
|
|
113
|
+
The following values can be configured:
|
|
114
|
+
|
|
115
|
+
* `id`: The MMKV instance's ID. If you want to use multiple instances, use different IDs. For example, you can separte the global app's storage and a logged-in user's storage. (required if `path` or `encryptionKey` fields are specified, otherwise defaults to: `'mmkv.default'`)
|
|
116
|
+
* `path`: The MMKV instance's root path. By default, MMKV stores file inside `$(Documents)/mmkv/`. You can customize MMKV's root directory on MMKV initialization (documentation: [iOS](https://github.com/Tencent/MMKV/wiki/iOS_advance#customize-location) / [Android](https://github.com/Tencent/MMKV/wiki/android_advance#customize-location))
|
|
117
|
+
* `encryptionKey`: The MMKV instance's encryption/decryption key. By default, MMKV stores all key-values in plain text on file, relying on iOS's/Android's sandbox to make sure the file is encrypted. Should you worry about information leaking, you can choose to encrypt MMKV. (documentation: [iOS](https://github.com/Tencent/MMKV/wiki/iOS_advance#encryption) / [Android](https://github.com/Tencent/MMKV/wiki/android_advance#encryption))
|
|
118
|
+
|
|
119
|
+
### Set
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
storage.set('user.name', 'Marc')
|
|
123
|
+
storage.set('user.age', 21)
|
|
124
|
+
storage.set('is-mmkv-fast-asf', true)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Get
|
|
128
|
+
|
|
129
|
+
```js
|
|
130
|
+
const username = storage.getString('user.name') // 'Marc'
|
|
131
|
+
const age = storage.getNumber('user.age') // 21
|
|
132
|
+
const isMmkvFastAsf = storage.getBoolean('is-mmkv-fast-asf') // true
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Keys
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
// checking if a specific key exists
|
|
139
|
+
const hasUsername = storage.contains('user.name')
|
|
140
|
+
|
|
141
|
+
// getting all keys
|
|
142
|
+
const keys = storage.getAllKeys() // ['user.name', 'user.age', 'is-mmkv-fast-asf']
|
|
143
|
+
|
|
144
|
+
// delete a specific key + value
|
|
145
|
+
storage.delete('user.name')
|
|
146
|
+
|
|
147
|
+
// delete all keys
|
|
148
|
+
storage.clearAll()
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Objects
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
const user = {
|
|
155
|
+
username: 'Marc',
|
|
156
|
+
age: 21
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Serialize the object into a JSON string
|
|
160
|
+
storage.set('user', JSON.stringify(user))
|
|
161
|
+
|
|
162
|
+
// Deserialize the JSON string into an object
|
|
163
|
+
const jsonUser = storage.getString('user') // { 'username': 'Marc', 'age': 21 }
|
|
164
|
+
const userObject = JSON.parse(jsonUser)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Encryption
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
// encrypt all data with a private key
|
|
171
|
+
storage.recrypt('hunter2')
|
|
172
|
+
|
|
173
|
+
// remove encryption
|
|
174
|
+
storage.recrypt(undefined)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Buffers
|
|
178
|
+
|
|
179
|
+
```js
|
|
180
|
+
storage.set('someToken', new Uint8Array([1, 100, 255]))
|
|
181
|
+
const buffer = storage.getBuffer('someToken')
|
|
182
|
+
console.log(buffer) // [1, 100, 255]
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Testing with Jest
|
|
186
|
+
|
|
187
|
+
A mocked MMKV instance is automatically used when testing with Jest, so you will be able to use `new MMKV()` as per normal in your tests. Refer to [example/test/MMKV.test.ts](example/test/MMKV.test.ts) for an example.
|
|
188
|
+
|
|
189
|
+
## Documentation
|
|
190
|
+
|
|
191
|
+
* [Hooks](./docs/HOOKS.md)
|
|
192
|
+
* [Value-change Listeners](./docs/LISTENERS.md)
|
|
193
|
+
* [Migrate from AsyncStorage](./docs/MIGRATE_FROM_ASYNC_STORAGE.md)
|
|
194
|
+
* [Using MMKV with redux-persist](./docs/WRAPPER_REDUX.md)
|
|
195
|
+
* [Using MMKV with mobx-persist-storage](./docs/WRAPPER_MOBX.md)
|
|
196
|
+
* [Using MMKV with mobx-persist](./docs/WRAPPER_MOBXPERSIST.md)
|
|
197
|
+
* [Using MMKV with zustand persist-middleware](./docs/WRAPPER_ZUSTAND_PERSIST_MIDDLEWARE.md)
|
|
198
|
+
* [Using MMKV with jotai](./docs/WRAPPER_JOTAI.md)
|
|
199
|
+
* [How is this library different from **react-native-mmkv-storage**?](https://github.com/mrousavy/react-native-mmkv/issues/100#issuecomment-886477361)
|
|
200
|
+
|
|
201
|
+
## Limitations
|
|
202
|
+
|
|
203
|
+
As the library uses JSI for synchronous native methods access, remote debugging (e.g. with Chrome) is no longer possible. Instead, you should use [Flipper](https://fbflipper.com).
|
|
204
|
+
|
|
205
|
+
## Debugging
|
|
206
|
+
|
|
207
|
+
Use [flipper-plugin-react-native-mmkv](https://github.com/muchobien/flipper-plugin-react-native-mmkv) to debug your MMKV storage using Flipper. You can also simply `console.log` an MMKV instance.
|
|
208
|
+
|
|
209
|
+
## Adopting at scale
|
|
210
|
+
|
|
211
|
+
react-native-mmkv is provided _as is_, I work on it in my free time.
|
|
212
|
+
|
|
213
|
+
If you're integrating react-native-mmkv in a production app, consider [funding this project](https://github.com/sponsors/mrousavy) and <a href="mailto:me@mrousavy.com?subject=Adopting react-native-mmkv at scale">contact me</a> to receive premium enterprise support, help with issues, prioritize bugfixes, request features, help at integrating react-native-mmkv, and more.
|
|
214
|
+
|
|
215
|
+
## Contributing
|
|
216
|
+
|
|
217
|
+
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
|
|
218
|
+
|
|
219
|
+
## License
|
|
220
|
+
|
|
221
|
+
MIT
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.9.0)
|
|
2
|
+
|
|
3
|
+
set (PACKAGE_NAME "react-native-mmkv")
|
|
4
|
+
set (BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
|
|
5
|
+
|
|
6
|
+
add_subdirectory(../MMKV/Core core)
|
|
7
|
+
|
|
8
|
+
include_directories(
|
|
9
|
+
../MMKV/Core
|
|
10
|
+
../cpp
|
|
11
|
+
"${NODE_MODULES_DIR}/react-native/React"
|
|
12
|
+
"${NODE_MODULES_DIR}/react-native/React/Base"
|
|
13
|
+
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
if(${REACT_NATIVE_VERSION} LESS 66)
|
|
17
|
+
file(
|
|
18
|
+
TO_CMAKE_PATH
|
|
19
|
+
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/jsi.cpp"
|
|
20
|
+
INCLUDE_JSI_CPP
|
|
21
|
+
)
|
|
22
|
+
endif()
|
|
23
|
+
|
|
24
|
+
add_library(reactnativemmkv # <-- Library name
|
|
25
|
+
SHARED
|
|
26
|
+
src/main/cpp/cpp-adapter.cpp
|
|
27
|
+
src/main/cpp/MmkvHostObject.cpp
|
|
28
|
+
../cpp/TypedArray.cpp
|
|
29
|
+
${INCLUDE_JSI_CPP} # only on older RN versions
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
set_target_properties(
|
|
33
|
+
reactnativemmkv PROPERTIES
|
|
34
|
+
CXX_STANDARD 17
|
|
35
|
+
CXX_EXTENSIONS OFF
|
|
36
|
+
POSITION_INDEPENDENT_CODE ON
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
file (GLOB LIBRN_DIR "${PREBUILT_DIR}/${ANDROID_ABI}")
|
|
40
|
+
|
|
41
|
+
find_library(
|
|
42
|
+
log-lib
|
|
43
|
+
log
|
|
44
|
+
)
|
|
45
|
+
find_library(
|
|
46
|
+
REACT_NATIVE_JNI_LIB
|
|
47
|
+
reactnativejni
|
|
48
|
+
PATHS ${LIBRN_DIR}
|
|
49
|
+
NO_CMAKE_FIND_ROOT_PATH
|
|
50
|
+
)
|
|
51
|
+
if(${REACT_NATIVE_VERSION} LESS 66)
|
|
52
|
+
# JSI lib didn't exist on RN 0.65 and before. Simply omit it.
|
|
53
|
+
set (JSI_LIB "")
|
|
54
|
+
else()
|
|
55
|
+
# RN 0.66 distributes libjsi.so, can be used instead of compiling jsi.cpp manually.
|
|
56
|
+
find_library(
|
|
57
|
+
JSI_LIB
|
|
58
|
+
jsi
|
|
59
|
+
PATHS ${LIBRN_DIR}
|
|
60
|
+
NO_CMAKE_FIND_ROOT_PATH
|
|
61
|
+
)
|
|
62
|
+
endif()
|
|
63
|
+
|
|
64
|
+
target_link_libraries(
|
|
65
|
+
reactnativemmkv
|
|
66
|
+
core
|
|
67
|
+
${log-lib}
|
|
68
|
+
${JSI_LIB}
|
|
69
|
+
${REACT_NATIVE_JNI_LIB}
|
|
70
|
+
android
|
|
71
|
+
)
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import groovy.json.JsonSlurper
|
|
2
|
+
import org.apache.tools.ant.filters.ReplaceTokens
|
|
3
|
+
import java.nio.file.Paths
|
|
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
|
+
|
|
23
|
+
buildscript {
|
|
24
|
+
repositories {
|
|
25
|
+
google()
|
|
26
|
+
jcenter()
|
|
27
|
+
maven {
|
|
28
|
+
url "https://plugins.gradle.org/m2/"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
dependencies {
|
|
33
|
+
classpath 'com.android.tools.build:gradle:4.2.2'
|
|
34
|
+
classpath 'de.undercouch:gradle-download-task:4.1.2'
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
apply plugin: 'com.android.library'
|
|
39
|
+
apply plugin: 'de.undercouch.download'
|
|
40
|
+
|
|
41
|
+
def getExtOrDefault(name) {
|
|
42
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['Mmkv_' + name]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
def getExtOrIntegerDefault(name) {
|
|
46
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['Mmkv_' + name]).toInteger()
|
|
47
|
+
}
|
|
48
|
+
|
|
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
|
|
55
|
+
def defaultDir = null
|
|
56
|
+
def androidSourcesDir = null
|
|
57
|
+
def androidSourcesName = 'React Native sources'
|
|
58
|
+
|
|
59
|
+
if (rootProject.ext.has('reactNativeAndroidRoot')) {
|
|
60
|
+
defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
|
|
61
|
+
androidSourcesDir = defaultDir.parentFile.toString()
|
|
62
|
+
} else if (findProject(':ReactAndroid') != null) {
|
|
63
|
+
sourceBuild = true
|
|
64
|
+
defaultDir = project(':ReactAndroid').projectDir
|
|
65
|
+
androidSourcesDir = defaultDir.parentFile.toString()
|
|
66
|
+
} else {
|
|
67
|
+
defaultDir = file("$nodeModules/react-native/android")
|
|
68
|
+
androidSourcesDir = defaultDir.parentFile.toString()
|
|
69
|
+
}
|
|
70
|
+
|
|
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}"
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
def prebuiltDir = sourceBuild
|
|
78
|
+
? "$nodeModules/react-native/ReactAndroid/src/main/jni/prebuilt/lib"
|
|
79
|
+
: "$buildDir/react-native-0*/jni"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def reactProperties = new Properties()
|
|
83
|
+
file("$nodeModules/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
|
|
84
|
+
def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger()
|
|
85
|
+
|
|
86
|
+
android {
|
|
87
|
+
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
|
|
88
|
+
buildToolsVersion getExtOrDefault('buildToolsVersion')
|
|
89
|
+
ndkVersion getExtOrDefault('ndkVersion')
|
|
90
|
+
|
|
91
|
+
defaultConfig {
|
|
92
|
+
minSdkVersion 21
|
|
93
|
+
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
|
|
94
|
+
versionCode 1
|
|
95
|
+
versionName "1.0"
|
|
96
|
+
externalNativeBuild {
|
|
97
|
+
cmake {
|
|
98
|
+
cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
|
|
99
|
+
arguments '-DANDROID_STL=c++_shared',
|
|
100
|
+
"-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
|
|
101
|
+
"-DNODE_MODULES_DIR=${nodeModules}",
|
|
102
|
+
"-DPREBUILT_DIR=${prebuiltDir}"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
ndk {
|
|
106
|
+
abiFilters (*reactNativeArchitectures())
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
dexOptions {
|
|
111
|
+
javaMaxHeapSize "4g"
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
externalNativeBuild {
|
|
115
|
+
cmake {
|
|
116
|
+
path "CMakeLists.txt"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
packagingOptions {
|
|
121
|
+
excludes = ["**/libc++_shared.so", "**/libfbjni.so", "**/libreactnativejni.so", "**/libjsi.so", "**/MANIFEST.MF"]
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
buildTypes {
|
|
125
|
+
release {
|
|
126
|
+
minifyEnabled false
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
lintOptions {
|
|
130
|
+
disable 'GradleCompatible'
|
|
131
|
+
}
|
|
132
|
+
compileOptions {
|
|
133
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
134
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
configurations {
|
|
138
|
+
extractHeaders
|
|
139
|
+
extractJNI
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
repositories {
|
|
144
|
+
mavenCentral()
|
|
145
|
+
google()
|
|
146
|
+
|
|
147
|
+
maven {
|
|
148
|
+
url defaultDir.toString()
|
|
149
|
+
name androidSourcesName
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
dependencies {
|
|
154
|
+
// noinspection GradleDynamicVersion
|
|
155
|
+
implementation 'com.facebook.react:react-native:+'
|
|
156
|
+
|
|
157
|
+
//noinspection GradleDynamicVersion
|
|
158
|
+
extractHeaders("com.facebook.fbjni:fbjni:+:headers")
|
|
159
|
+
//noinspection GradleDynamicVersion
|
|
160
|
+
extractJNI("com.facebook.fbjni:fbjni:+")
|
|
161
|
+
|
|
162
|
+
if (!sourceBuild) {
|
|
163
|
+
def buildType = "debug"
|
|
164
|
+
tasks.all({ task ->
|
|
165
|
+
if (task.name == "buildCMakeRelease") {
|
|
166
|
+
buildType = "release"
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
def rnAarMatcher = "**/react-native/**/*${buildType}.aar"
|
|
170
|
+
if (REACT_NATIVE_VERSION < 69) {
|
|
171
|
+
rnAarMatcher = "**/**/*.aar"
|
|
172
|
+
}
|
|
173
|
+
def rnAAR = fileTree("${defaultDir.toString()}").matching({ it.include rnAarMatcher }).singleFile
|
|
174
|
+
extractJNI(files(rnAAR))
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// third-party-ndk deps headers
|
|
179
|
+
// mostly a copy of https://github.com/software-mansion/react-native-reanimated/blob/master/android/build.gradle#L115
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def customDownloadsDir = System.getenv("REACT_NATIVE_DOWNLOADS_DIR")
|
|
183
|
+
def downloadsDir = customDownloadsDir ? new File(customDownloadsDir) : new File("$buildDir/downloads")
|
|
184
|
+
def thirdPartyNdkDir = new File("$buildDir/third-party-ndk")
|
|
185
|
+
def thirdPartyVersionsFile = new File("${androidSourcesDir.toString()}/ReactAndroid/gradle.properties")
|
|
186
|
+
def thirdPartyVersions = new Properties()
|
|
187
|
+
thirdPartyVersions.load(new FileInputStream(thirdPartyVersionsFile))
|
|
188
|
+
|
|
189
|
+
def BOOST_VERSION = thirdPartyVersions["BOOST_VERSION"]
|
|
190
|
+
def boost_file = new File(downloadsDir, "boost_${BOOST_VERSION}.tar.gz")
|
|
191
|
+
def DOUBLE_CONVERSION_VERSION = thirdPartyVersions["DOUBLE_CONVERSION_VERSION"]
|
|
192
|
+
def double_conversion_file = new File(downloadsDir, "double-conversion-${DOUBLE_CONVERSION_VERSION}.tar.gz")
|
|
193
|
+
def FOLLY_VERSION = thirdPartyVersions["FOLLY_VERSION"]
|
|
194
|
+
def folly_file = new File(downloadsDir, "folly-${FOLLY_VERSION}.tar.gz")
|
|
195
|
+
def GLOG_VERSION = thirdPartyVersions["GLOG_VERSION"]
|
|
196
|
+
def glog_file = new File(downloadsDir, "glog-${GLOG_VERSION}.tar.gz")
|
|
197
|
+
|
|
198
|
+
task createNativeDepsDirectories {
|
|
199
|
+
doLast {
|
|
200
|
+
downloadsDir.mkdirs()
|
|
201
|
+
thirdPartyNdkDir.mkdirs()
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
206
|
+
def transformedVersion = BOOST_VERSION.replace("_", ".")
|
|
207
|
+
def srcUrl = "https://boostorg.jfrog.io/artifactory/main/release/${transformedVersion}/source/boost_${BOOST_VERSION}.tar.gz"
|
|
208
|
+
if (REACT_NATIVE_VERSION < 69) {
|
|
209
|
+
srcUrl = "https://github.com/react-native-community/boost-for-react-native/releases/download/v${transformedVersion}-0/boost_${BOOST_VERSION}.tar.gz"
|
|
210
|
+
}
|
|
211
|
+
src(srcUrl)
|
|
212
|
+
onlyIfNewer(true)
|
|
213
|
+
overwrite(false)
|
|
214
|
+
dest(boost_file)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
task prepareBoost(dependsOn: downloadBoost, type: Copy) {
|
|
218
|
+
from(tarTree(resources.gzip(downloadBoost.dest)))
|
|
219
|
+
from("src/main/jni/third-party/boost/Android.mk")
|
|
220
|
+
include("Android.mk", "boost_${BOOST_VERSION}/boost/**/*.hpp", "boost/boost/**/*.hpp")
|
|
221
|
+
includeEmptyDirs = false
|
|
222
|
+
into("$thirdPartyNdkDir") // /boost_X_XX_X
|
|
223
|
+
doLast {
|
|
224
|
+
file("$thirdPartyNdkDir/boost_${BOOST_VERSION}").renameTo("$thirdPartyNdkDir/boost")
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
task downloadDoubleConversion(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
229
|
+
src("https://github.com/google/double-conversion/archive/v${DOUBLE_CONVERSION_VERSION}.tar.gz")
|
|
230
|
+
onlyIfNewer(true)
|
|
231
|
+
overwrite(false)
|
|
232
|
+
dest(double_conversion_file)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
task prepareDoubleConversion(dependsOn: downloadDoubleConversion, type: Copy) {
|
|
236
|
+
from(tarTree(downloadDoubleConversion.dest))
|
|
237
|
+
from("src/main/jni/third-party/double-conversion/Android.mk")
|
|
238
|
+
include("double-conversion-${DOUBLE_CONVERSION_VERSION}/src/**/*", "Android.mk")
|
|
239
|
+
filesMatching("*/src/**/*", { fname -> fname.path = "double-conversion/${fname.name}" })
|
|
240
|
+
includeEmptyDirs = false
|
|
241
|
+
into("$thirdPartyNdkDir/double-conversion")
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
task downloadFolly(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
245
|
+
src("https://github.com/facebook/folly/archive/v${FOLLY_VERSION}.tar.gz")
|
|
246
|
+
onlyIfNewer(true)
|
|
247
|
+
overwrite(false)
|
|
248
|
+
dest(folly_file)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
task prepareFolly(dependsOn: downloadFolly, type: Copy) {
|
|
252
|
+
from(tarTree(downloadFolly.dest))
|
|
253
|
+
from("src/main/jni/third-party/folly/Android.mk")
|
|
254
|
+
include("folly-${FOLLY_VERSION}/folly/**/*", "Android.mk")
|
|
255
|
+
eachFile { fname -> fname.path = (fname.path - "folly-${FOLLY_VERSION}/") }
|
|
256
|
+
includeEmptyDirs = false
|
|
257
|
+
into("$thirdPartyNdkDir/folly")
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
task downloadGlog(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
261
|
+
src("https://github.com/google/glog/archive/v${GLOG_VERSION}.tar.gz")
|
|
262
|
+
onlyIfNewer(true)
|
|
263
|
+
overwrite(false)
|
|
264
|
+
dest(glog_file)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
task prepareGlog(dependsOn: downloadGlog, type: Copy) {
|
|
268
|
+
from(tarTree(downloadGlog.dest))
|
|
269
|
+
from("src/main/jni/third-party/glog/")
|
|
270
|
+
include("glog-${GLOG_VERSION}/src/**/*", "Android.mk", "config.h")
|
|
271
|
+
includeEmptyDirs = false
|
|
272
|
+
filesMatching("**/*.h.in") {
|
|
273
|
+
filter(ReplaceTokens, tokens: [
|
|
274
|
+
ac_cv_have_unistd_h : "1",
|
|
275
|
+
ac_cv_have_stdint_h : "1",
|
|
276
|
+
ac_cv_have_systypes_h : "1",
|
|
277
|
+
ac_cv_have_inttypes_h : "1",
|
|
278
|
+
ac_cv_have_libgflags : "0",
|
|
279
|
+
ac_google_start_namespace : "namespace google {",
|
|
280
|
+
ac_cv_have_uint16_t : "1",
|
|
281
|
+
ac_cv_have_u_int16_t : "1",
|
|
282
|
+
ac_cv_have___uint16 : "0",
|
|
283
|
+
ac_google_end_namespace : "}",
|
|
284
|
+
ac_cv_have___builtin_expect : "1",
|
|
285
|
+
ac_google_namespace : "google",
|
|
286
|
+
ac_cv___attribute___noinline : "__attribute__ ((noinline))",
|
|
287
|
+
ac_cv___attribute___noreturn : "__attribute__ ((noreturn))",
|
|
288
|
+
ac_cv___attribute___printf_4_5: "__attribute__((__format__ (__printf__, 4, 5)))"
|
|
289
|
+
])
|
|
290
|
+
it.path = (it.name - ".in")
|
|
291
|
+
}
|
|
292
|
+
into("$thirdPartyNdkDir/glog")
|
|
293
|
+
|
|
294
|
+
doLast {
|
|
295
|
+
copy {
|
|
296
|
+
from(fileTree(dir: "$thirdPartyNdkDir/glog", includes: ["stl_logging.h", "logging.h", "raw_logging.h", "vlog_is_on.h", "**/src/glog/log_severity.h"]).files)
|
|
297
|
+
includeEmptyDirs = false
|
|
298
|
+
into("$thirdPartyNdkDir/glog/exported/glog")
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
task prepareThirdPartyNdkHeaders {
|
|
304
|
+
if (!boost_file.exists()) {
|
|
305
|
+
dependsOn(prepareBoost)
|
|
306
|
+
}
|
|
307
|
+
if (!double_conversion_file.exists()) {
|
|
308
|
+
dependsOn(prepareDoubleConversion)
|
|
309
|
+
}
|
|
310
|
+
if (!folly_file.exists()) {
|
|
311
|
+
dependsOn(prepareFolly)
|
|
312
|
+
}
|
|
313
|
+
if (!glog_file.exists()) {
|
|
314
|
+
dependsOn(prepareGlog)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
prepareThirdPartyNdkHeaders.mustRunAfter createNativeDepsDirectories
|
|
319
|
+
|
|
320
|
+
task extractAARHeaders {
|
|
321
|
+
doLast {
|
|
322
|
+
configurations.extractHeaders.files.each {
|
|
323
|
+
def file = it.absoluteFile
|
|
324
|
+
copy {
|
|
325
|
+
from zipTree(file)
|
|
326
|
+
into "$buildDir/$file.name"
|
|
327
|
+
include "**/*.h"
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
extractAARHeaders.mustRunAfter prepareThirdPartyNdkHeaders
|
|
333
|
+
|
|
334
|
+
task extractJNIFiles {
|
|
335
|
+
doLast {
|
|
336
|
+
configurations.extractJNI.files.each {
|
|
337
|
+
def file = it.absoluteFile
|
|
338
|
+
|
|
339
|
+
copy {
|
|
340
|
+
from zipTree(file)
|
|
341
|
+
into "$buildDir/$file.name"
|
|
342
|
+
include "jni/**/*"
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
extractJNIFiles.mustRunAfter extractAARHeaders
|
|
348
|
+
|
|
349
|
+
def nativeBuildDependsOn(dependsOnTask, variant) {
|
|
350
|
+
def buildTasks = tasks.findAll({ task ->
|
|
351
|
+
!task.name.contains("Clean") && (task.name.contains("externalNative") || task.name.contains("CMake")) })
|
|
352
|
+
if (variant != null) {
|
|
353
|
+
buildTasks = buildTasks.findAll({ task -> task.name.contains(variant) })
|
|
354
|
+
}
|
|
355
|
+
buildTasks.forEach { task -> task.dependsOn(dependsOnTask) }
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
afterEvaluate {
|
|
359
|
+
if (sourceBuild) {
|
|
360
|
+
if (REACT_NATIVE_VERSION < 68) {
|
|
361
|
+
nativeBuildDependsOn(":ReactAndroid:packageReactNdkLibsForBuck", null)
|
|
362
|
+
} else {
|
|
363
|
+
nativeBuildDependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck", "Debug")
|
|
364
|
+
nativeBuildDependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck", "Rel")
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
nativeBuildDependsOn(extractAARHeaders, null)
|
|
368
|
+
nativeBuildDependsOn(extractJNIFiles, null)
|
|
369
|
+
nativeBuildDependsOn(prepareThirdPartyNdkHeaders, null)
|
|
370
|
+
}
|
|
371
|
+
}
|