react-native-mmkv 2.4.4 → 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/README.md CHANGED
@@ -174,6 +174,14 @@ storage.recrypt('hunter2')
174
174
  storage.recrypt(undefined)
175
175
  ```
176
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
+
177
185
  ## Testing with Jest
178
186
 
179
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.
@@ -7,6 +7,7 @@ add_subdirectory(../MMKV/Core core)
7
7
 
8
8
  include_directories(
9
9
  ../MMKV/Core
10
+ ../cpp
10
11
  "${NODE_MODULES_DIR}/react-native/React"
11
12
  "${NODE_MODULES_DIR}/react-native/React/Base"
12
13
  "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi"
@@ -14,7 +15,7 @@ include_directories(
14
15
 
15
16
  if(${REACT_NATIVE_VERSION} LESS 66)
16
17
  file(
17
- TO_CMAKE_PATH
18
+ TO_CMAKE_PATH
18
19
  "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/jsi.cpp"
19
20
  INCLUDE_JSI_CPP
20
21
  )
@@ -24,6 +25,7 @@ add_library(reactnativemmkv # <-- Library name
24
25
  SHARED
25
26
  src/main/cpp/cpp-adapter.cpp
26
27
  src/main/cpp/MmkvHostObject.cpp
28
+ ../cpp/TypedArray.cpp
27
29
  ${INCLUDE_JSI_CPP} # only on older RN versions
28
30
  )
29
31
 
@@ -7,9 +7,11 @@
7
7
  //
8
8
 
9
9
  #include "MmkvHostObject.h"
10
+ #include "TypedArray.h"
10
11
  #include <MMKV.h>
11
12
  #include <android/log.h>
12
13
  #include <string>
14
+ #include <vector>
13
15
 
14
16
  MmkvHostObject::MmkvHostObject(const std::string& instanceId, std::string path, std::string cryptKey) {
15
17
  __android_log_print(ANDROID_LOG_INFO, "RNMMKV", "Creating MMKV instance \"%s\"... (Path: %s, Encryption-Key: %s)",
@@ -65,16 +67,37 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
65
67
  }
66
68
 
67
69
  auto keyName = arguments[0].getString(runtime).utf8(runtime);
70
+
68
71
  if (arguments[1].isBool()) {
72
+ // bool
69
73
  instance->set(arguments[1].getBool(), keyName);
70
74
  } else if (arguments[1].isNumber()) {
75
+ // number
71
76
  instance->set(arguments[1].getNumber(), keyName);
72
77
  } else if (arguments[1].isString()) {
78
+ // string
73
79
  auto stringValue = arguments[1].getString(runtime).utf8(runtime);
74
80
  instance->set(stringValue, keyName);
81
+ } else if (arguments[1].isObject()) {
82
+ // object
83
+ auto object = arguments[1].asObject(runtime);
84
+ if (isTypedArray(runtime, object)) {
85
+ // Uint8Array
86
+ auto typedArray = getTypedArray(runtime, object);
87
+ auto bufferValue = typedArray.getBuffer(runtime);
88
+ mmkv::MMBuffer buffer(bufferValue.data(runtime),
89
+ bufferValue.size(runtime),
90
+ mmkv::MMBufferCopyFlag::MMBufferNoCopy);
91
+ instance->set(buffer, keyName);
92
+ } else {
93
+ // unknown object
94
+ throw jsi::JSError(runtime, "MMKV::set: 'value' argument is an object, but not of type Uint8Array!");
95
+ }
75
96
  } else {
76
- throw jsi::JSError(runtime, "MMKV::set: 'value' argument is not of type bool, number or string!");
97
+ // unknown type
98
+ throw jsi::JSError(runtime, "MMKV::set: 'value' argument is not of type bool, number, string or buffer!");
77
99
  }
100
+
78
101
  return jsi::Value::undefined();
79
102
  });
80
103
  }
@@ -151,6 +174,37 @@ jsi::Value MmkvHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& pro
151
174
  });
152
175
  }
153
176
 
177
+
178
+ if (propName == "getBuffer") {
179
+ // MMKV.getBuffer(key: string)
180
+ return jsi::Function::createFromHostFunction(runtime,
181
+ jsi::PropNameID::forAscii(runtime, funcName),
182
+ 1, // key
183
+ [this](jsi::Runtime& runtime,
184
+ const jsi::Value& thisValue,
185
+ const jsi::Value* arguments,
186
+ size_t count) -> jsi::Value {
187
+ if (!arguments[0].isString()) {
188
+ throw jsi::JSError(runtime, "First argument ('key') has to be of type string!");
189
+ }
190
+
191
+ auto keyName = arguments[0].getString(runtime).utf8(runtime);
192
+ mmkv::MMBuffer buffer;
193
+ bool hasValue = instance->getBytes(keyName, buffer);
194
+ if (hasValue) {
195
+ auto length = buffer.length();
196
+ TypedArray<TypedArrayKind::Uint8Array> array(runtime, length);
197
+ auto data = static_cast<const unsigned char*>(buffer.getPtr());
198
+ std::vector<unsigned char> vector(length);
199
+ vector.assign(data, data + length);
200
+ array.update(runtime, vector);
201
+ return array;
202
+ } else {
203
+ return jsi::Value::undefined();
204
+ }
205
+ });
206
+ }
207
+
154
208
  if (propName == "contains") {
155
209
  // MMKV.contains(key: string)
156
210
  return jsi::Function::createFromHostFunction(runtime,
@@ -0,0 +1,341 @@
1
+ //
2
+ // TypedArray.cpp
3
+ // react-native-mmkv
4
+ //
5
+ // Created by Marc Rousavy on 11.10.2022.
6
+ // Originally created by Expo (expo-gl)
7
+ //
8
+
9
+ #include "TypedArray.h"
10
+
11
+ #include <unordered_map>
12
+
13
+ template <TypedArrayKind T>
14
+ using ContentType = typename typedArrayTypeMap<T>::type;
15
+
16
+ enum class Prop
17
+ {
18
+ Buffer, // "buffer"
19
+ Constructor, // "constructor"
20
+ Name, // "name"
21
+ Proto, // "__proto__"
22
+ Length, // "length"
23
+ ByteLength, // "byteLength"
24
+ ByteOffset, // "offset"
25
+ IsView, // "isView"
26
+ ArrayBuffer, // "ArrayBuffer"
27
+ Int8Array, // "Int8Array"
28
+ Int16Array, // "Int16Array"
29
+ Int32Array, // "Int32Array"
30
+ Uint8Array, // "Uint8Array"
31
+ Uint8ClampedArray, // "Uint8ClampedArray"
32
+ Uint16Array, // "Uint16Array"
33
+ Uint32Array, // "Uint32Array"
34
+ Float32Array, // "Float32Array"
35
+ Float64Array, // "Float64Array"
36
+ };
37
+
38
+ class PropNameIDCache
39
+ {
40
+ public:
41
+ const jsi::PropNameID &get(jsi::Runtime &runtime, Prop prop)
42
+ {
43
+ if (!this->props[prop])
44
+ {
45
+ this->props[prop] = std::make_unique<jsi::PropNameID>(createProp(runtime, prop));
46
+ }
47
+ return *(this->props[prop]);
48
+ }
49
+
50
+ const jsi::PropNameID &getConstructorNameProp(jsi::Runtime &runtime, TypedArrayKind kind);
51
+
52
+ void invalidate()
53
+ {
54
+ props.erase(props.begin(), props.end());
55
+ }
56
+
57
+ private:
58
+ std::unordered_map<Prop, std::unique_ptr<jsi::PropNameID>> props;
59
+
60
+ jsi::PropNameID createProp(jsi::Runtime &runtime, Prop prop);
61
+ };
62
+
63
+ PropNameIDCache propNameIDCache;
64
+
65
+ void invalidateJsiPropNameIDCache()
66
+ {
67
+ propNameIDCache.invalidate();
68
+ }
69
+
70
+ TypedArrayKind getTypedArrayKindForName(const std::string &name);
71
+
72
+ TypedArrayBase::TypedArrayBase(jsi::Runtime &runtime, size_t size, TypedArrayKind kind)
73
+ : TypedArrayBase(
74
+ runtime,
75
+ runtime.global()
76
+ .getProperty(runtime, propNameIDCache.getConstructorNameProp(runtime, kind))
77
+ .asObject(runtime)
78
+ .asFunction(runtime)
79
+ .callAsConstructor(runtime, {static_cast<double>(size)})
80
+ .asObject(runtime)) {}
81
+
82
+ TypedArrayBase::TypedArrayBase(jsi::Runtime &runtime, const jsi::Object &obj)
83
+ : jsi::Object(jsi::Value(runtime, obj).asObject(runtime)) {}
84
+
85
+ TypedArrayKind TypedArrayBase::getKind(jsi::Runtime &runtime) const
86
+ {
87
+ auto constructorName = this->getProperty(runtime, propNameIDCache.get(runtime, Prop::Constructor))
88
+ .asObject(runtime)
89
+ .getProperty(runtime, propNameIDCache.get(runtime, Prop::Name))
90
+ .asString(runtime)
91
+ .utf8(runtime);
92
+ return getTypedArrayKindForName(constructorName);
93
+ };
94
+
95
+ size_t TypedArrayBase::size(jsi::Runtime &runtime) const
96
+ {
97
+ return getProperty(runtime, propNameIDCache.get(runtime, Prop::Length)).asNumber();
98
+ }
99
+
100
+ size_t TypedArrayBase::length(jsi::Runtime &runtime) const
101
+ {
102
+ return getProperty(runtime, propNameIDCache.get(runtime, Prop::Length)).asNumber();
103
+ }
104
+
105
+ size_t TypedArrayBase::byteLength(jsi::Runtime &runtime) const
106
+ {
107
+ return getProperty(runtime, propNameIDCache.get(runtime, Prop::ByteLength)).asNumber();
108
+ }
109
+
110
+ size_t TypedArrayBase::byteOffset(jsi::Runtime &runtime) const
111
+ {
112
+ return getProperty(runtime, propNameIDCache.get(runtime, Prop::ByteOffset)).asNumber();
113
+ }
114
+
115
+ bool TypedArrayBase::hasBuffer(jsi::Runtime &runtime) const
116
+ {
117
+ auto buffer = getProperty(runtime, propNameIDCache.get(runtime, Prop::Buffer));
118
+ return buffer.isObject() && buffer.asObject(runtime).isArrayBuffer(runtime);
119
+ }
120
+
121
+ std::vector<uint8_t> TypedArrayBase::toVector(jsi::Runtime &runtime)
122
+ {
123
+ auto start =
124
+ reinterpret_cast<uint8_t *>(getBuffer(runtime).data(runtime) + byteOffset(runtime));
125
+ auto end = start + byteLength(runtime);
126
+ return std::vector<uint8_t>(start, end);
127
+ }
128
+
129
+ jsi::ArrayBuffer TypedArrayBase::getBuffer(jsi::Runtime &runtime) const
130
+ {
131
+ auto buffer = getProperty(runtime, propNameIDCache.get(runtime, Prop::Buffer));
132
+ if (buffer.isObject() && buffer.asObject(runtime).isArrayBuffer(runtime))
133
+ {
134
+ return buffer.asObject(runtime).getArrayBuffer(runtime);
135
+ }
136
+ else
137
+ {
138
+ throw std::runtime_error("no ArrayBuffer attached");
139
+ }
140
+ }
141
+
142
+ bool isTypedArray(jsi::Runtime &runtime, const jsi::Object &jsObj)
143
+ {
144
+ auto jsVal = runtime.global()
145
+ .getProperty(runtime, propNameIDCache.get(runtime, Prop::ArrayBuffer))
146
+ .asObject(runtime)
147
+ .getProperty(runtime, propNameIDCache.get(runtime, Prop::IsView))
148
+ .asObject(runtime)
149
+ .asFunction(runtime)
150
+ .callWithThis(runtime, runtime.global(), {jsi::Value(runtime, jsObj)});
151
+ if (jsVal.isBool())
152
+ {
153
+ return jsVal.getBool();
154
+ }
155
+ else
156
+ {
157
+ throw std::runtime_error("value is not a boolean");
158
+ }
159
+ }
160
+
161
+ TypedArrayBase getTypedArray(jsi::Runtime &runtime, const jsi::Object &jsObj)
162
+ {
163
+ auto jsVal = runtime.global()
164
+ .getProperty(runtime, propNameIDCache.get(runtime, Prop::ArrayBuffer))
165
+ .asObject(runtime)
166
+ .getProperty(runtime, propNameIDCache.get(runtime, Prop::IsView))
167
+ .asObject(runtime)
168
+ .asFunction(runtime)
169
+ .callWithThis(runtime, runtime.global(), {jsi::Value(runtime, jsObj)});
170
+ if (jsVal.isBool())
171
+ {
172
+ return TypedArrayBase(runtime, jsObj);
173
+ }
174
+ else
175
+ {
176
+ throw std::runtime_error("value is not a boolean");
177
+ }
178
+ }
179
+
180
+ std::vector<uint8_t> arrayBufferToVector(jsi::Runtime &runtime, jsi::Object &jsObj)
181
+ {
182
+ if (!jsObj.isArrayBuffer(runtime))
183
+ {
184
+ throw std::runtime_error("Object is not an ArrayBuffer");
185
+ }
186
+ auto jsArrayBuffer = jsObj.getArrayBuffer(runtime);
187
+
188
+ uint8_t *dataBlock = jsArrayBuffer.data(runtime);
189
+ size_t blockSize =
190
+ jsArrayBuffer.getProperty(runtime, propNameIDCache.get(runtime, Prop::ByteLength)).asNumber();
191
+ return std::vector<uint8_t>(dataBlock, dataBlock + blockSize);
192
+ }
193
+
194
+ void arrayBufferUpdate(
195
+ jsi::Runtime &runtime,
196
+ jsi::ArrayBuffer &buffer,
197
+ std::vector<uint8_t> data,
198
+ size_t offset)
199
+ {
200
+ uint8_t *dataBlock = buffer.data(runtime);
201
+ size_t blockSize = buffer.size(runtime);
202
+ if (data.size() > blockSize)
203
+ {
204
+ throw jsi::JSError(runtime, "ArrayBuffer is to small to fit data");
205
+ }
206
+ std::copy(data.begin(), data.end(), dataBlock + offset);
207
+ }
208
+
209
+ template <TypedArrayKind T>
210
+ TypedArray<T>::TypedArray(jsi::Runtime &runtime, size_t size) : TypedArrayBase(runtime, size, T){};
211
+
212
+ template <TypedArrayKind T>
213
+ TypedArray<T>::TypedArray(jsi::Runtime &runtime, std::vector<ContentType<T>> data)
214
+ : TypedArrayBase(runtime, data.size(), T)
215
+ {
216
+ update(runtime, data);
217
+ };
218
+
219
+ template <TypedArrayKind T>
220
+ TypedArray<T>::TypedArray(TypedArrayBase &&base) : TypedArrayBase(std::move(base)) {}
221
+
222
+ template <TypedArrayKind T>
223
+ std::vector<ContentType<T>> TypedArray<T>::toVector(jsi::Runtime &runtime)
224
+ {
225
+ auto start =
226
+ reinterpret_cast<ContentType<T> *>(getBuffer(runtime).data(runtime) + byteOffset(runtime));
227
+ auto end = start + size(runtime);
228
+ return std::vector<ContentType<T>>(start, end);
229
+ }
230
+
231
+ template <TypedArrayKind T>
232
+ void TypedArray<T>::update(jsi::Runtime &runtime, const std::vector<ContentType<T>> &data)
233
+ {
234
+ if (data.size() != size(runtime))
235
+ {
236
+ throw jsi::JSError(runtime, "TypedArray can only be updated with a vector of the same size");
237
+ }
238
+ uint8_t *rawData = getBuffer(runtime).data(runtime) + byteOffset(runtime);
239
+ std::copy(data.begin(), data.end(), reinterpret_cast<ContentType<T> *>(rawData));
240
+ }
241
+
242
+ const jsi::PropNameID &PropNameIDCache::getConstructorNameProp(
243
+ jsi::Runtime &runtime,
244
+ TypedArrayKind kind)
245
+ {
246
+ switch (kind)
247
+ {
248
+ case TypedArrayKind::Int8Array:
249
+ return get(runtime, Prop::Int8Array);
250
+ case TypedArrayKind::Int16Array:
251
+ return get(runtime, Prop::Int16Array);
252
+ case TypedArrayKind::Int32Array:
253
+ return get(runtime, Prop::Int32Array);
254
+ case TypedArrayKind::Uint8Array:
255
+ return get(runtime, Prop::Uint8Array);
256
+ case TypedArrayKind::Uint8ClampedArray:
257
+ return get(runtime, Prop::Uint8ClampedArray);
258
+ case TypedArrayKind::Uint16Array:
259
+ return get(runtime, Prop::Uint16Array);
260
+ case TypedArrayKind::Uint32Array:
261
+ return get(runtime, Prop::Uint32Array);
262
+ case TypedArrayKind::Float32Array:
263
+ return get(runtime, Prop::Float32Array);
264
+ case TypedArrayKind::Float64Array:
265
+ return get(runtime, Prop::Float64Array);
266
+ }
267
+ }
268
+
269
+ jsi::PropNameID PropNameIDCache::createProp(jsi::Runtime &runtime, Prop prop)
270
+ {
271
+ auto create = [&](const std::string &propName)
272
+ {
273
+ return jsi::PropNameID::forUtf8(runtime, propName);
274
+ };
275
+ switch (prop)
276
+ {
277
+ case Prop::Buffer:
278
+ return create("buffer");
279
+ case Prop::Constructor:
280
+ return create("constructor");
281
+ case Prop::Name:
282
+ return create("name");
283
+ case Prop::Proto:
284
+ return create("__proto__");
285
+ case Prop::Length:
286
+ return create("length");
287
+ case Prop::ByteLength:
288
+ return create("byteLength");
289
+ case Prop::ByteOffset:
290
+ return create("byteOffset");
291
+ case Prop::IsView:
292
+ return create("isView");
293
+ case Prop::ArrayBuffer:
294
+ return create("ArrayBuffer");
295
+ case Prop::Int8Array:
296
+ return create("Int8Array");
297
+ case Prop::Int16Array:
298
+ return create("Int16Array");
299
+ case Prop::Int32Array:
300
+ return create("Int32Array");
301
+ case Prop::Uint8Array:
302
+ return create("Uint8Array");
303
+ case Prop::Uint8ClampedArray:
304
+ return create("Uint8ClampedArray");
305
+ case Prop::Uint16Array:
306
+ return create("Uint16Array");
307
+ case Prop::Uint32Array:
308
+ return create("Uint32Array");
309
+ case Prop::Float32Array:
310
+ return create("Float32Array");
311
+ case Prop::Float64Array:
312
+ return create("Float64Array");
313
+ }
314
+ }
315
+
316
+ std::unordered_map<std::string, TypedArrayKind> nameToKindMap = {
317
+ {"Int8Array", TypedArrayKind::Int8Array},
318
+ {"Int16Array", TypedArrayKind::Int16Array},
319
+ {"Int32Array", TypedArrayKind::Int32Array},
320
+ {"Uint8Array", TypedArrayKind::Uint8Array},
321
+ {"Uint8ClampedArray", TypedArrayKind::Uint8ClampedArray},
322
+ {"Uint16Array", TypedArrayKind::Uint16Array},
323
+ {"Uint32Array", TypedArrayKind::Uint32Array},
324
+ {"Float32Array", TypedArrayKind::Float32Array},
325
+ {"Float64Array", TypedArrayKind::Float64Array},
326
+ };
327
+
328
+ TypedArrayKind getTypedArrayKindForName(const std::string &name)
329
+ {
330
+ return nameToKindMap.at(name);
331
+ }
332
+
333
+ template class TypedArray<TypedArrayKind::Int8Array>;
334
+ template class TypedArray<TypedArrayKind::Int16Array>;
335
+ template class TypedArray<TypedArrayKind::Int32Array>;
336
+ template class TypedArray<TypedArrayKind::Uint8Array>;
337
+ template class TypedArray<TypedArrayKind::Uint8ClampedArray>;
338
+ template class TypedArray<TypedArrayKind::Uint16Array>;
339
+ template class TypedArray<TypedArrayKind::Uint32Array>;
340
+ template class TypedArray<TypedArrayKind::Float32Array>;
341
+ template class TypedArray<TypedArrayKind::Float64Array>;
@@ -0,0 +1,175 @@
1
+ //
2
+ // TypedArray.h
3
+ // react-native-mmkv
4
+ //
5
+ // Created by Marc Rousavy on 11.10.2022.
6
+ // Originally created by Expo (expo-gl)
7
+ //
8
+
9
+ #pragma once
10
+
11
+ #include <jsi/jsi.h>
12
+
13
+ namespace jsi = facebook::jsi;
14
+
15
+ enum class TypedArrayKind
16
+ {
17
+ Int8Array,
18
+ Int16Array,
19
+ Int32Array,
20
+ Uint8Array,
21
+ Uint8ClampedArray,
22
+ Uint16Array,
23
+ Uint32Array,
24
+ Float32Array,
25
+ Float64Array,
26
+ };
27
+
28
+ template <TypedArrayKind T>
29
+ class TypedArray;
30
+
31
+ template <TypedArrayKind T>
32
+ struct typedArrayTypeMap;
33
+ template <>
34
+ struct typedArrayTypeMap<TypedArrayKind::Int8Array>
35
+ {
36
+ typedef int8_t type;
37
+ };
38
+ template <>
39
+ struct typedArrayTypeMap<TypedArrayKind::Int16Array>
40
+ {
41
+ typedef int16_t type;
42
+ };
43
+ template <>
44
+ struct typedArrayTypeMap<TypedArrayKind::Int32Array>
45
+ {
46
+ typedef int32_t type;
47
+ };
48
+ template <>
49
+ struct typedArrayTypeMap<TypedArrayKind::Uint8Array>
50
+ {
51
+ typedef uint8_t type;
52
+ };
53
+ template <>
54
+ struct typedArrayTypeMap<TypedArrayKind::Uint8ClampedArray>
55
+ {
56
+ typedef uint8_t type;
57
+ };
58
+ template <>
59
+ struct typedArrayTypeMap<TypedArrayKind::Uint16Array>
60
+ {
61
+ typedef uint16_t type;
62
+ };
63
+ template <>
64
+ struct typedArrayTypeMap<TypedArrayKind::Uint32Array>
65
+ {
66
+ typedef uint32_t type;
67
+ };
68
+ template <>
69
+ struct typedArrayTypeMap<TypedArrayKind::Float32Array>
70
+ {
71
+ typedef float type;
72
+ };
73
+ template <>
74
+ struct typedArrayTypeMap<TypedArrayKind::Float64Array>
75
+ {
76
+ typedef double type;
77
+ };
78
+
79
+ void invalidateJsiPropNameIDCache();
80
+
81
+ class TypedArrayBase : public jsi::Object
82
+ {
83
+ public:
84
+ template <TypedArrayKind T>
85
+ using ContentType = typename typedArrayTypeMap<T>::type;
86
+
87
+ TypedArrayBase(jsi::Runtime &, size_t, TypedArrayKind);
88
+ TypedArrayBase(jsi::Runtime &, const jsi::Object &);
89
+ TypedArrayBase(TypedArrayBase &&) = default;
90
+ TypedArrayBase &operator=(TypedArrayBase &&) = default;
91
+
92
+ TypedArrayKind getKind(jsi::Runtime &runtime) const;
93
+
94
+ template <TypedArrayKind T>
95
+ TypedArray<T> get(jsi::Runtime &runtime) const &;
96
+ template <TypedArrayKind T>
97
+ TypedArray<T> get(jsi::Runtime &runtime) &&;
98
+ template <TypedArrayKind T>
99
+ TypedArray<T> as(jsi::Runtime &runtime) const &;
100
+ template <TypedArrayKind T>
101
+ TypedArray<T> as(jsi::Runtime &runtime) &&;
102
+
103
+ size_t size(jsi::Runtime &runtime) const;
104
+ size_t length(jsi::Runtime &runtime) const;
105
+ size_t byteLength(jsi::Runtime &runtime) const;
106
+ size_t byteOffset(jsi::Runtime &runtime) const;
107
+ bool hasBuffer(jsi::Runtime &runtime) const;
108
+
109
+ std::vector<uint8_t> toVector(jsi::Runtime &runtime);
110
+ jsi::ArrayBuffer getBuffer(jsi::Runtime &runtime) const;
111
+
112
+ private:
113
+ template <TypedArrayKind>
114
+ friend class TypedArray;
115
+ };
116
+
117
+ bool isTypedArray(jsi::Runtime &runtime, const jsi::Object &jsObj);
118
+ TypedArrayBase getTypedArray(jsi::Runtime &runtime, const jsi::Object &jsObj);
119
+
120
+ std::vector<uint8_t> arrayBufferToVector(jsi::Runtime &runtime, jsi::Object &jsObj);
121
+ void arrayBufferUpdate(
122
+ jsi::Runtime &runtime,
123
+ jsi::ArrayBuffer &buffer,
124
+ std::vector<uint8_t> data,
125
+ size_t offset);
126
+
127
+ template <TypedArrayKind T>
128
+ class TypedArray : public TypedArrayBase
129
+ {
130
+ public:
131
+ TypedArray(jsi::Runtime &runtime, size_t size);
132
+ TypedArray(jsi::Runtime &runtime, std::vector<ContentType<T>> data);
133
+ TypedArray(TypedArrayBase &&base);
134
+ TypedArray(TypedArray &&) = default;
135
+ TypedArray &operator=(TypedArray &&) = default;
136
+
137
+ std::vector<ContentType<T>> toVector(jsi::Runtime &runtime);
138
+ void update(jsi::Runtime &runtime, const std::vector<ContentType<T>> &data);
139
+ };
140
+
141
+ template <TypedArrayKind T>
142
+ TypedArray<T> TypedArrayBase::get(jsi::Runtime &runtime) const &
143
+ {
144
+ assert(getKind(runtime) == T);
145
+ (void)runtime; // when assert is disabled we need to mark this as used
146
+ return TypedArray<T>(jsi::Value(runtime, jsi::Value(runtime, *this).asObject(runtime)));
147
+ }
148
+
149
+ template <TypedArrayKind T>
150
+ TypedArray<T> TypedArrayBase::get(jsi::Runtime &runtime) &&
151
+ {
152
+ assert(getKind(runtime) == T);
153
+ (void)runtime; // when assert is disabled we need to mark this as used
154
+ return TypedArray<T>(std::move(*this));
155
+ }
156
+
157
+ template <TypedArrayKind T>
158
+ TypedArray<T> TypedArrayBase::as(jsi::Runtime &runtime) const &
159
+ {
160
+ if (getKind(runtime) != T)
161
+ {
162
+ throw jsi::JSError(runtime, "Object is not a TypedArray");
163
+ }
164
+ return get<T>(runtime);
165
+ }
166
+
167
+ template <TypedArrayKind T>
168
+ TypedArray<T> TypedArrayBase::as(jsi::Runtime &runtime) &&
169
+ {
170
+ if (getKind(runtime) != T)
171
+ {
172
+ throw jsi::JSError(runtime, "Object is not a TypedArray");
173
+ }
174
+ return std::move(*this).get<T>(runtime);
175
+ }
@@ -7,8 +7,8 @@
7
7
  objects = {
8
8
 
9
9
  /* Begin PBXBuildFile section */
10
- 5E555C0D2413F4C50049A1A2 /* Mmkv.mm in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* Mmkv.mm */; };
11
10
  B81384EA26E23A8500A8507D /* MmkvHostObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = B81384E926E23A8500A8507D /* MmkvHostObject.mm */; };
11
+ B8A8A9BE28F5797400345076 /* MmkvModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = B8A8A9BD28F5797400345076 /* MmkvModule.mm */; };
12
12
  B8CC270225E65597009808A2 /* JSIUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = B8CC270125E65597009808A2 /* JSIUtils.mm */; };
13
13
  /* End PBXBuildFile section */
14
14
 
@@ -26,10 +26,11 @@
26
26
 
27
27
  /* Begin PBXFileReference section */
28
28
  134814201AA4EA6300B7C361 /* libMmkv.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMmkv.a; sourceTree = BUILT_PRODUCTS_DIR; };
29
- B3E7B5891CC2AC0600A0062D /* Mmkv.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Mmkv.mm; sourceTree = "<group>"; };
30
29
  B81384E926E23A8500A8507D /* MmkvHostObject.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MmkvHostObject.mm; sourceTree = "<group>"; };
31
30
  B81384EB26E23A8D00A8507D /* MmkvHostObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MmkvHostObject.h; sourceTree = "<group>"; };
32
- B865949C25E63C5C002102DB /* Mmkv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mmkv.h; sourceTree = "<group>"; };
31
+ B8A8A9BC28F5797400345076 /* MmkvModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MmkvModule.h; sourceTree = "<group>"; };
32
+ B8A8A9BD28F5797400345076 /* MmkvModule.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MmkvModule.mm; sourceTree = "<group>"; };
33
+ B8A8A9BF28F5798100345076 /* cpp */ = {isa = PBXFileReference; lastKnownFileType = folder; name = cpp; path = ../cpp; sourceTree = "<group>"; };
33
34
  B8CC270125E65597009808A2 /* JSIUtils.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = JSIUtils.mm; sourceTree = "<group>"; };
34
35
  B8CC270425E655AD009808A2 /* JSIUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSIUtils.h; sourceTree = "<group>"; };
35
36
  /* End PBXFileReference section */
@@ -60,8 +61,9 @@
60
61
  B81384E926E23A8500A8507D /* MmkvHostObject.mm */,
61
62
  B8CC270425E655AD009808A2 /* JSIUtils.h */,
62
63
  B8CC270125E65597009808A2 /* JSIUtils.mm */,
63
- B865949C25E63C5C002102DB /* Mmkv.h */,
64
- B3E7B5891CC2AC0600A0062D /* Mmkv.mm */,
64
+ B8A8A9BC28F5797400345076 /* MmkvModule.h */,
65
+ B8A8A9BD28F5797400345076 /* MmkvModule.mm */,
66
+ B8A8A9BF28F5798100345076 /* cpp */,
65
67
  134814211AA4EA7D00B7C361 /* Products */,
66
68
  );
67
69
  sourceTree = "<group>";
@@ -123,8 +125,8 @@
123
125
  isa = PBXSourcesBuildPhase;
124
126
  buildActionMask = 2147483647;
125
127
  files = (
126
- 5E555C0D2413F4C50049A1A2 /* Mmkv.mm in Sources */,
127
128
  B81384EA26E23A8500A8507D /* MmkvHostObject.mm in Sources */,
129
+ B8A8A9BE28F5797400345076 /* MmkvModule.mm in Sources */,
128
130
  B8CC270225E65597009808A2 /* JSIUtils.mm in Sources */,
129
131
  );
130
132
  runOnlyForDeploymentPostprocessing = 0;