diff --git a/bun.lockb b/bun.lockb index 954892e68..5cd403d74 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/example/babel.config.js b/example/babel.config.js index 734a32ffa..8cfc651a3 100644 --- a/example/babel.config.js +++ b/example/babel.config.js @@ -14,4 +14,4 @@ module.exports = { }, ], ], -}; +} diff --git a/example/index.js b/example/index.js index 117ddcae4..5c5c0c512 100644 --- a/example/index.js +++ b/example/index.js @@ -1,5 +1,5 @@ -import { AppRegistry } from 'react-native'; -import App from './src/App'; -import { name as appName } from './app.json'; +import { AppRegistry } from 'react-native' +import App from './src/App' +import { name as appName } from './app.json' -AppRegistry.registerComponent(appName, () => App); +AppRegistry.registerComponent(appName, () => App) diff --git a/example/jest.config.js b/example/jest.config.js index 8eb675e9b..1fbafc9cb 100644 --- a/example/jest.config.js +++ b/example/jest.config.js @@ -1,3 +1,3 @@ module.exports = { preset: 'react-native', -}; +} diff --git a/example/metro.config.js b/example/metro.config.js index b82321455..902a4d0e0 100644 --- a/example/metro.config.js +++ b/example/metro.config.js @@ -1,11 +1,11 @@ -const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); -const path = require('path'); -const escape = require('escape-string-regexp'); -const exclusionList = require('metro-config/src/defaults/exclusionList'); -const pak = require('../package.json'); +const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config') +const path = require('path') +const escape = require('escape-string-regexp') +const exclusionList = require('metro-config/src/defaults/exclusionList') +const pak = require('../package.json') -const root = path.resolve(__dirname, '..'); -const modules = Object.keys({ ...pak.peerDependencies }); +const root = path.resolve(__dirname, '..') +const modules = Object.keys({ ...pak.peerDependencies }) /** * Metro configuration @@ -27,8 +27,8 @@ const config = { ), extraNodeModules: modules.reduce((acc, name) => { - acc[name] = path.join(__dirname, 'node_modules', name); - return acc; + acc[name] = path.join(__dirname, 'node_modules', name) + return acc }, {}), }, @@ -40,6 +40,6 @@ const config = { }, }), }, -}; +} -module.exports = mergeConfig(getDefaultConfig(__dirname), config); +module.exports = mergeConfig(getDefaultConfig(__dirname), config) diff --git a/example/package.json b/example/package.json index 7f95df662..e6fd42d68 100644 --- a/example/package.json +++ b/example/package.json @@ -28,8 +28,8 @@ "@types/deep-equal": "^1.0.4", "babel-plugin-module-resolver": "^5.0.2", "del-cli": "^5.1.0", - "eslint": "^9.9.1", "eslint-config-prettier": "^9.1.0", + "eslint": "^8.57.0", "eslint-plugin-prettier": "^5.2.1", "nitro-codegen": "*", "prettier": "^3.3.3", @@ -46,6 +46,7 @@ "@react-native", "prettier" ], + "plugins": ["prettier"], "rules": { "prettier/prettier": [ "warn", diff --git a/example/react-native.config.js b/example/react-native.config.js index a7c48b037..c8f1d838e 100644 --- a/example/react-native.config.js +++ b/example/react-native.config.js @@ -7,4 +7,4 @@ module.exports = { // root: path.join(__dirname, '..'), // }, }, -}; +} diff --git a/packages/nitrogen/package.json b/packages/nitrogen/package.json index c594f345d..073669258 100644 --- a/packages/nitrogen/package.json +++ b/packages/nitrogen/package.json @@ -74,6 +74,7 @@ "@react-native", "prettier" ], + "plugins": ["prettier"], "rules": { "prettier/prettier": [ "warn", diff --git a/packages/react-native-nitro-image/android/src/main/cpp/cpp-adapter.cpp b/packages/react-native-nitro-image/android/src/main/cpp/cpp-adapter.cpp index b373180c0..19261d16d 100644 --- a/packages/react-native-nitro-image/android/src/main/cpp/cpp-adapter.cpp +++ b/packages/react-native-nitro-image/android/src/main/cpp/cpp-adapter.cpp @@ -1,7 +1,7 @@ #include -#include "JFunc_void_std__string.hpp" #include "JFunc_void_Person.hpp" +#include "JFunc_void_std__string.hpp" #include "JHybridImageFactorySpec.hpp" #include "JHybridImageSpec.hpp" #include "JHybridKotlinTestObjectSpec.hpp" diff --git a/packages/react-native-nitro-image/android/src/main/java/com/margelo/nitro/image/KotlinTestObject.kt b/packages/react-native-nitro-image/android/src/main/java/com/margelo/nitro/image/KotlinTestObject.kt index feae44a38..e0be27496 100644 --- a/packages/react-native-nitro-image/android/src/main/java/com/margelo/nitro/image/KotlinTestObject.kt +++ b/packages/react-native-nitro-image/android/src/main/java/com/margelo/nitro/image/KotlinTestObject.kt @@ -1,6 +1,7 @@ package com.margelo.nitro.image import com.margelo.nitro.core.AnyMap +import com.margelo.nitro.core.AnyValue import com.margelo.nitro.core.ArrayBuffer import com.margelo.nitro.core.Promise import java.nio.ByteBuffer @@ -34,6 +35,12 @@ class KotlinTestObject: HybridKotlinTestObjectSpec() { map.setString("string", "String!") map.setBoolean("bool", true) map.setBigInt("bigint", 893256789) + map.setAnyObject("object", mapOf("first" to AnyValue(1), "second" to AnyValue("string"), "third" to AnyValue( + mapOf("nested" to AnyValue(true)) + ))) + map.setAnyArray("array", arrayOf(AnyValue(11), AnyValue(true), AnyValue(33.5), AnyValue("string"), AnyValue( + arrayOf(AnyValue("nested"), AnyValue(true)) + ))) return map } diff --git a/packages/react-native-nitro-image/package.json b/packages/react-native-nitro-image/package.json index b4ab9eeba..3169d6e31 100644 --- a/packages/react-native-nitro-image/package.json +++ b/packages/react-native-nitro-image/package.json @@ -84,6 +84,7 @@ "@react-native", "prettier" ], + "plugins": ["prettier"], "rules": { "prettier/prettier": [ "warn", diff --git a/packages/react-native-nitro-modules/README.md b/packages/react-native-nitro-modules/README.md index b1e07bcbc..d61cb6e0d 100644 --- a/packages/react-native-nitro-modules/README.md +++ b/packages/react-native-nitro-modules/README.md @@ -191,7 +191,7 @@ The following C++ / JS types are supported out of the box: { ... } std::shared_ptr<AnyMap> AnyMapHolder 🟡  (#57) - AnyMap 🟡  (#61) + AnyMap ArrayBuffer diff --git a/packages/react-native-nitro-modules/android/src/main/cpp/JNIOnLoad.cpp b/packages/react-native-nitro-modules/android/src/main/cpp/JNIOnLoad.cpp index d3f8f2683..269c851a6 100644 --- a/packages/react-native-nitro-modules/android/src/main/cpp/JNIOnLoad.cpp +++ b/packages/react-native-nitro-modules/android/src/main/cpp/JNIOnLoad.cpp @@ -1,6 +1,7 @@ /// Entry point for JNI. #include "JAnyMap.hpp" +#include "JAnyValue.hpp" #include "JArrayBuffer.hpp" #include "JHybridObjectRegistry.hpp" #include "JPromise.hpp" @@ -19,6 +20,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { JHybridObjectRegistry::registerNatives(); JArrayBuffer::registerNatives(); JAnyMap::registerNatives(); + JAnyValue::registerNatives(); JPromise::registerNatives(); }); } diff --git a/packages/react-native-nitro-modules/android/src/main/cpp/core/ByteBufferArrayBuffer.hpp b/packages/react-native-nitro-modules/android/src/main/cpp/core/ByteBufferArrayBuffer.hpp index ba00836c1..adce2a747 100644 --- a/packages/react-native-nitro-modules/android/src/main/cpp/core/ByteBufferArrayBuffer.hpp +++ b/packages/react-native-nitro-modules/android/src/main/cpp/core/ByteBufferArrayBuffer.hpp @@ -18,25 +18,25 @@ using namespace facebook; /** * Represents an `ArrayBuffer` that holds a `ByteBuffer`. */ -class ByteBufferArrayBuffer : public ArrayBuffer { +class ByteBufferArrayBuffer final : public ArrayBuffer { public: - explicit ByteBufferArrayBuffer(jni::alias_ref byteBuffer) : _byteBuffer(jni::make_global(byteBuffer)) { + explicit ByteBufferArrayBuffer(const jni::alias_ref& byteBuffer) : _byteBuffer(jni::make_global(byteBuffer)) { _byteBuffer->order(jni::JByteOrder::bigEndian()); } public: - uint8_t* data() override { + [[nodiscard]] uint8_t* data() override { return _byteBuffer->getDirectBytes(); } - size_t size() const override { + [[nodiscard]] size_t size() const override { return _byteBuffer->getDirectSize(); } - bool isOwner() const noexcept override { + [[nodiscard]] bool isOwner() const noexcept override { return _byteBuffer != nullptr && _byteBuffer->isDirect(); } public: - jni::alias_ref getBuffer() const { + [[nodiscard]] jni::alias_ref getBuffer() const { return _byteBuffer; } diff --git a/packages/react-native-nitro-modules/android/src/main/cpp/core/JAnyMap.hpp b/packages/react-native-nitro-modules/android/src/main/cpp/core/JAnyMap.hpp index 50ecc7ae7..d73dbdca8 100644 --- a/packages/react-native-nitro-modules/android/src/main/cpp/core/JAnyMap.hpp +++ b/packages/react-native-nitro-modules/android/src/main/cpp/core/JAnyMap.hpp @@ -8,6 +8,7 @@ #pragma once #include "AnyMap.hpp" +#include "JAnyValue.hpp" #include namespace margelo::nitro { @@ -15,9 +16,9 @@ namespace margelo::nitro { using namespace facebook; /** - * Represents a Promise implemented in Java. + * Represents an `AnyMap` implemented in Java. */ -class JAnyMap : public jni::HybridClass { +class JAnyMap final : public jni::HybridClass { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/core/AnyMap;"; @@ -88,6 +89,25 @@ class JAnyMap : public jni::HybridClass { std::string getString(const std::string& key) { return _map->getString(key); } + jni::alias_ref getAnyArray(const std::string& key) { + const auto& vector = _map->getArray(key); + auto javaArray = jni::JArrayClass::newArray(vector.size()); + for (size_t i = 0; i < vector.size(); i++) { + auto value = JAnyValue::create(vector[i]); + javaArray->setElement(i, value.get()); + } + return javaArray; + } + jni::alias_ref getAnyObject(const std::string& key) { + const auto& map = _map->getObject(key); + auto javaMap = jni::JHashMap::create(map.size()); + for (const auto& entry : map) { + auto string = jni::make_jstring(entry.first); + auto value = JAnyValue::create(entry.second); + javaMap->put(string, value); + } + return javaMap; + } protected: void setNull(const std::string& key) { @@ -105,6 +125,24 @@ class JAnyMap : public jni::HybridClass { void setString(const std::string& key, const std::string& value) { _map->setString(key, value); } + void setAnyArray(const std::string& key, jni::alias_ref value) { + std::vector vector; + size_t size = value->size(); + vector.reserve(size); + for (size_t i = 0; i < size; i++) { + auto anyValue = value->getElement(i); + vector.push_back(anyValue->cthis()->getValue()); + } + _map->setArray(key, vector); + } + void setAnyObject(const std::string& key, const jni::alias_ref& value) { + std::unordered_map map; + map.reserve(value->size()); + for (const auto& entry : *value) { + map.emplace(entry.first->toStdString(), entry.second->cthis()->getValue()); + } + _map->setObject(key, map); + } public: std::shared_ptr getMap() const { @@ -138,12 +176,16 @@ class JAnyMap : public jni::HybridClass { makeNativeMethod("getBoolean", JAnyMap::getBoolean), makeNativeMethod("getBigInt", JAnyMap::getBigInt), makeNativeMethod("getString", JAnyMap::getString), + makeNativeMethod("getAnyArray", JAnyMap::getAnyArray), + makeNativeMethod("getAnyObject", JAnyMap::getAnyObject), // set makeNativeMethod("setNull", JAnyMap::setNull), makeNativeMethod("setDouble", JAnyMap::setDouble), makeNativeMethod("setBoolean", JAnyMap::setBoolean), makeNativeMethod("setBigInt", JAnyMap::setBigInt), makeNativeMethod("setString", JAnyMap::setString), + makeNativeMethod("setAnyArray", JAnyMap::setAnyArray), + makeNativeMethod("setAnyObject", JAnyMap::setAnyObject), }); } }; diff --git a/packages/react-native-nitro-modules/android/src/main/cpp/core/JAnyValue.hpp b/packages/react-native-nitro-modules/android/src/main/cpp/core/JAnyValue.hpp new file mode 100644 index 000000000..451262c40 --- /dev/null +++ b/packages/react-native-nitro-modules/android/src/main/cpp/core/JAnyValue.hpp @@ -0,0 +1,191 @@ +// +// JAnyMap.hpp +// react-native-nitro +// +// Created by Marc Rousavy on 14.07.24. +// + +#pragma once + +#include "AnyMap.hpp" +#include + +namespace margelo::nitro { + +using namespace facebook; + +/** + * Represents an `AnyValue` (variant) implemented in Java. + */ +class JAnyValue final : public jni::HybridClass { +public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/core/AnyValue;"; + + /** + * Represents an `Array` + */ + using JAnyArray = jni::JArrayClass; + /** + * Represents a `Map` + */ + using JAnyObject = jni::JMap; + +public: + /** + * Create a new `JAnyValue` from an existing `AnyValue`. + */ + static jni::local_ref create(AnyValue&& value) { + return newObjectCxxArgs(std::move(value)); + } + static jni::local_ref create(const AnyValue& value) { + return newObjectCxxArgs(value); + } + +protected: + static jni::local_ref initHybridNull(jni::alias_ref) { + return makeCxxInstance(/* null */); + } + static jni::local_ref initHybridDouble(jni::alias_ref, double value) { + return makeCxxInstance(value); + } + static jni::local_ref initHybridBoolean(jni::alias_ref, bool value) { + return makeCxxInstance(value); + } + static jni::local_ref initHybridLong(jni::alias_ref, int64_t value) { + return makeCxxInstance(value); + } + static jni::local_ref initHybridString(jni::alias_ref, const std::string& value) { + return makeCxxInstance(value); + } + static jni::local_ref initHybridAnyArray(jni::alias_ref, jni::alias_ref value) { + std::vector vector; + size_t size = value->size(); + vector.reserve(size); + for (size_t i = 0; i < size; i++) { + auto anyValue = value->getElement(i); + vector.push_back(anyValue->cthis()->getValue()); + } + return makeCxxInstance(std::move(vector)); + } + static jni::local_ref initHybridAnyObject(jni::alias_ref, jni::alias_ref value) { + std::unordered_map map; + map.reserve(value->size()); + for (const auto& entry : *value) { + map.emplace(entry.first->toStdString(), entry.second->cthis()->getValue()); + } + return makeCxxInstance(std::move(map)); + } + +private: + // Java initializers + explicit JAnyValue(/* null */) : _value(std::monostate()) {} + explicit JAnyValue(double value) : _value(value) {} + explicit JAnyValue(bool value) : _value(value) {} + explicit JAnyValue(int64_t value) : _value(value) {} + explicit JAnyValue(const std::string& value) : _value(value) {} + explicit JAnyValue(AnyArray&& value) : _value(std::move(value)) {} + explicit JAnyValue(AnyObject&& value) : _value(std::move(value)) {} + // C++ initializers + explicit JAnyValue(const AnyValue& value) : _value(value) {} + explicit JAnyValue(AnyValue&& value) : _value(std::move(value)) {} + +protected: + bool isNull() { + return std::holds_alternative(_value); + } + bool isDouble() { + return std::holds_alternative(_value); + } + bool isBoolean() { + return std::holds_alternative(_value); + } + bool isBigInt() { + return std::holds_alternative(_value); + } + bool isString() { + return std::holds_alternative(_value); + } + bool isAnyArray() { + return std::holds_alternative(_value); + } + bool isAnyObject() { + return std::holds_alternative(_value); + } + +protected: + double asDouble() { + return std::get(_value); + } + bool asBoolean() { + return std::get(_value); + } + int64_t asBigInt() { + return std::get(_value); + } + std::string asString() { + return std::get(_value); + } + jni::alias_ref asAnyArray() { + auto vector = std::get(_value); + auto javaArray = jni::JArrayClass::newArray(vector.size()); + for (size_t i = 0; i < vector.size(); i++) { + auto value = JAnyValue::create(vector[i]); + javaArray->setElement(i, value.get()); + } + return javaArray; + } + jni::alias_ref asAnyObject() { + auto map = std::get(_value); + auto javaMap = jni::JHashMap::create(map.size()); + for (const auto& entry : map) { + auto key = jni::make_jstring(entry.first); + auto value = JAnyValue::create(entry.second); + javaMap->put(key, value); + } + return javaMap; + } + +public: + [[nodiscard]] const AnyValue& getValue() const noexcept { + return _value; + } + +private: + friend HybridBase; + using HybridBase::HybridBase; + AnyValue _value; + +public: + static void registerNatives() { + registerHybrid({ + // init + makeNativeMethod("initHybrid", JAnyValue::initHybridNull), + makeNativeMethod("initHybrid", JAnyValue::initHybridDouble), + makeNativeMethod("initHybrid", JAnyValue::initHybridBoolean), + makeNativeMethod("initHybrid", JAnyValue::initHybridLong), + makeNativeMethod("initHybrid", JAnyValue::initHybridString), + makeNativeMethod("initHybrid", JAnyValue::initHybridAnyArray), + makeNativeMethod("initHybrid", JAnyValue::initHybridAnyObject), + // is + makeNativeMethod("isNull", JAnyValue::isNull), + makeNativeMethod("isDouble", JAnyValue::isDouble), + makeNativeMethod("isBoolean", JAnyValue::isBoolean), + makeNativeMethod("isBigInt", JAnyValue::isBigInt), + makeNativeMethod("isString", JAnyValue::isString), + makeNativeMethod("isAnyArray", JAnyValue::isAnyArray), + makeNativeMethod("isAnyObject", JAnyValue::isAnyObject), + // get + makeNativeMethod("asDouble", JAnyValue::asDouble), + makeNativeMethod("asBoolean", JAnyValue::asBoolean), + makeNativeMethod("asBigInt", JAnyValue::asBigInt), + makeNativeMethod("asString", JAnyValue::asString), + makeNativeMethod("asAnyArray", JAnyValue::asAnyArray), + makeNativeMethod("asAnyObject", JAnyValue::asAnyObject), + }); + } +}; + +using JAnyArray = JAnyValue::JAnyArray; +using JAnyObject = JAnyValue::JAnyObject; + +} // namespace margelo::nitro diff --git a/packages/react-native-nitro-modules/android/src/main/cpp/core/JArrayBuffer.hpp b/packages/react-native-nitro-modules/android/src/main/cpp/core/JArrayBuffer.hpp index 7989a6798..0d51ed28d 100644 --- a/packages/react-native-nitro-modules/android/src/main/cpp/core/JArrayBuffer.hpp +++ b/packages/react-native-nitro-modules/android/src/main/cpp/core/JArrayBuffer.hpp @@ -22,7 +22,7 @@ using namespace facebook; * Represents a `ArrayBuffer` that can either hold a `ByteBuffer` (owning), * or unknown/foreign memory, potentially from JS (non-owning). */ -struct JArrayBuffer : public jni::HybridClass { +class JArrayBuffer final : public jni::HybridClass { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/core/ArrayBuffer;"; diff --git a/packages/react-native-nitro-modules/android/src/main/cpp/core/JHybridObject.hpp b/packages/react-native-nitro-modules/android/src/main/cpp/core/JHybridObject.hpp index d90c87f52..8194e7026 100644 --- a/packages/react-native-nitro-modules/android/src/main/cpp/core/JHybridObject.hpp +++ b/packages/react-native-nitro-modules/android/src/main/cpp/core/JHybridObject.hpp @@ -19,11 +19,11 @@ using namespace facebook; * HybridData is passed up from inherited members, so this acts like a base class * and has to be inherited as "virtual" in C++ to properly avoid creating multiple `HybridObject` instances. */ -struct JHybridObject : public jni::HybridClass, public virtual HybridObject { +class JHybridObject : public jni::HybridClass, public virtual HybridObject { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/core/HybridObject;"; - virtual ~JHybridObject() = default; + ~JHybridObject() override = default; private: friend HybridBase; diff --git a/packages/react-native-nitro-modules/android/src/main/cpp/core/JPromise.hpp b/packages/react-native-nitro-modules/android/src/main/cpp/core/JPromise.hpp index 01bde023b..ac26ecd0b 100644 --- a/packages/react-native-nitro-modules/android/src/main/cpp/core/JPromise.hpp +++ b/packages/react-native-nitro-modules/android/src/main/cpp/core/JPromise.hpp @@ -16,7 +16,7 @@ using namespace facebook; /** * Represents a Promise implemented in Java. */ -class JPromise : public jni::HybridClass { +class JPromise final : public jni::HybridClass { public: static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/core/Promise;"; using OnResolvedFunc = std::function)>; diff --git a/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/AnyMap.kt b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/AnyMap.kt index d177034d4..7873db919 100644 --- a/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/AnyMap.kt +++ b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/AnyMap.kt @@ -6,7 +6,7 @@ import com.facebook.proguard.annotations.DoNotStrip /** * Represents an untyped map of string keys with associated values. - * This is like an "`any`" JS object. + * This is like a JS [`object`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object). */ @Suppress("KotlinJniMissingFunction") @Keep @@ -46,12 +46,16 @@ class AnyMap { external fun getBoolean(key: String): Boolean external fun getBigInt(key: String): Long external fun getString(key: String): String + external fun getAnyArray(key: String): AnyArray + external fun getAnyObject(key: String): AnyObject external fun setNull(key: String) external fun setDouble(key: String, value: Double) external fun setBoolean(key: String, value: Boolean) external fun setBigInt(key: String, value: Long) external fun setString(key: String, value: String) + external fun setAnyArray(key: String, value: AnyArray) + external fun setAnyObject(key: String, value: AnyObject) private external fun initHybrid(): HybridData } diff --git a/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/AnyValue.kt b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/AnyValue.kt new file mode 100644 index 000000000..5a312fb8d --- /dev/null +++ b/packages/react-native-nitro-modules/android/src/main/java/com/margelo/nitro/core/AnyValue.kt @@ -0,0 +1,153 @@ +package com.margelo.nitro.core + +import androidx.annotation.Keep +import com.facebook.jni.HybridData +import com.facebook.proguard.annotations.DoNotStrip + +typealias AnyArray = Array +typealias AnyObject = Map + +/** + * Represents a value that can be any of the following types: + * - `null` + * - [Double] + * - [Boolean] + * - [Long] + * - [String] + * - [AnyArray] ([Array]``) + * - [AnyObject] ([Map]``) + */ +@Suppress("KotlinJniMissingFunction") +@Keep +@DoNotStrip +class AnyValue { + private val mHybridData: HybridData + + /** + * Create a new [AnyValue] that holds `null`. + */ + constructor() { + mHybridData = initHybrid() + } + + /** + * Create a new [AnyValue] that holds the given [Double] + */ + constructor(value: Double) { + mHybridData = initHybrid(value) + } + + /** + * Create a new [AnyValue] that holds the given [Boolean] + */ + constructor(value: Boolean) { + mHybridData = initHybrid(value) + } + + /** + * Create a new [AnyValue] that holds the given [Long] + */ + constructor(value: Long) { + mHybridData = initHybrid(value) + } + + /** + * Create a new [AnyValue] that holds the given [String] + */ + constructor(value: String) { + mHybridData = initHybrid(value) + } + + /** + * Create a new [AnyValue] that holds the given [AnyArray] + */ + constructor(value: AnyArray) { + mHybridData = initHybrid(value) + } + + /** + * Create a new [AnyValue] that holds the given [AnyObject] + */ + constructor(value: AnyObject) { + mHybridData = initHybrid(value) + } + + /** + * Gets whether this [AnyValue] instance is holding a `null`. + */ + external fun isNull(): Boolean + + /** + * Gets whether this [AnyValue] instance is holding a [Double] value. + */ + external fun isDouble(): Boolean + + /** + * Gets whether this [AnyValue] instance is holding a [Boolean] value. + */ + external fun isBoolean(): Boolean + + /** + * Gets whether this [AnyValue] instance is holding a [Long] value. + */ + external fun isBigInt(): Boolean + + /** + * Gets whether this [AnyValue] instance is holding a [String] value. + */ + external fun isString(): Boolean + + /** + * Gets whether this [AnyValue] instance is holding an [AnyArray] value. + */ + external fun isAnyArray(): Boolean + + /** + * Gets whether this [AnyValue] instance is holding an [AnyObject] value. + */ + external fun isAnyObject(): Boolean + + /** + * Get the [Double] value this [AnyValue] is holding. + * @throws Error if this [AnyValue] is not holding a [Double] (see [isDouble]`()`) + */ + external fun asDouble(): Double + + /** + * Get the [Boolean] value this [AnyValue] is holding. + * @throws Error if this [AnyValue] is not holding a [Boolean] (see [isBoolean]`()`) + */ + external fun asBoolean(): Boolean + + /** + * Get the [Long] value this [AnyValue] is holding. + * @throws Error if this [AnyValue] is not holding a [Long] (see [isLong]`()`) + */ + external fun asBigInt(): Long + + /** + * Get the [String] value this [AnyValue] is holding. + * @throws Error if this [AnyValue] is not holding a [String] (see [isString]`()`) + */ + external fun asString(): String + + /** + * Get the [AnyArray] value this [AnyValue] is holding. + * @throws Error if this [AnyValue] is not holding an [AnyArray] (see [isAnyArray]`()`) + */ + external fun asAnyArray(): AnyArray + + /** + * Get the [AnyObject] value this [AnyValue] is holding. + * @throws Error if this [AnyValue] is not holding an [AnyObject] (see [isAnyObject]`()`) + */ + external fun asAnyObject(): AnyObject + + private external fun initHybrid(): HybridData + private external fun initHybrid(value: Double): HybridData + private external fun initHybrid(value: Boolean): HybridData + private external fun initHybrid(value: Long): HybridData + private external fun initHybrid(value: String): HybridData + private external fun initHybrid(value: AnyArray): HybridData + private external fun initHybrid(value: AnyObject): HybridData +} \ No newline at end of file diff --git a/packages/react-native-nitro-modules/package.json b/packages/react-native-nitro-modules/package.json index a732a12c1..615a0c626 100644 --- a/packages/react-native-nitro-modules/package.json +++ b/packages/react-native-nitro-modules/package.json @@ -105,6 +105,7 @@ "@react-native", "prettier" ], + "plugins": ["prettier"], "rules": { "prettier/prettier": [ "warn", diff --git a/packages/react-native-nitro-modules/src/AnyMap.ts b/packages/react-native-nitro-modules/src/AnyMap.ts index 0573bbdfb..6ec7acdf2 100644 --- a/packages/react-native-nitro-modules/src/AnyMap.ts +++ b/packages/react-native-nitro-modules/src/AnyMap.ts @@ -18,5 +18,8 @@ export type ValueType = * - Objects of primitives (`Record`) * - Arrays of arrays or objects * - Objects of arrays or objects + * + * @note It is recommended to always use typed `interface`s instead of `AnyMap` for + * both type safety, as well as better performance. */ export type AnyMap = Record