├── .circleci └── config.yml ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .gitmodules ├── .yarnrc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── android ├── .project ├── .settings │ └── org.eclipse.buildship.core.prefs ├── CMakeLists.txt ├── build.gradle ├── cpp-adapter.cpp ├── gradle.properties └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── reactnativeleveldb │ ├── LeveldbModule.java │ └── LeveldbPackage.java ├── babel.config.js ├── cpp ├── react-native-leveldb.cpp └── react-native-leveldb.h ├── example ├── .bundle │ └── config ├── .gitignore ├── .ruby-version ├── Gemfile ├── Gemfile.lock ├── android │ ├── .project │ ├── .settings │ │ └── org.eclipse.buildship.core.prefs │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── reactnativeleveldb │ │ │ │ └── ReactNativeFlipper.java │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── reactnativeleveldb │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.java │ │ │ ├── jni │ │ │ │ ├── Android.mk │ │ │ │ ├── MainApplicationModuleProvider.cpp │ │ │ │ ├── MainApplicationTurboModuleManagerDelegate.cpp │ │ │ │ ├── MainApplicationTurboModuleManagerDelegate.h │ │ │ │ └── MainComponentsRegistry.cpp │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ └── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── release │ │ │ └── java │ │ │ └── com │ │ │ └── reactnativeleveldb │ │ │ └── ReactNativeFlipper.java │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios │ ├── .xcode.env │ ├── File.swift │ ├── LeveldbExample-Bridging-Header.h │ ├── LeveldbExample.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── LeveldbExample.xcscheme │ ├── LeveldbExample.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ ├── LeveldbExample │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ └── main.m │ ├── Podfile │ └── Podfile.lock ├── metro.config.js ├── package.json ├── react-native.config.js ├── src │ ├── App.tsx │ ├── benchmark.tsx │ ├── example.ts │ └── test-util.tsx └── yarn.lock ├── ios ├── Leveldb.h ├── Leveldb.mm └── Leveldb.xcodeproj │ └── project.pbxproj ├── lefthook.yml ├── package.json ├── react-native-leveldb.podspec ├── scripts └── bootstrap.js ├── src ├── fake.test.ts ├── fake.ts └── index.ts ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | executors: 4 | default: 5 | docker: 6 | - image: circleci/node:10 7 | working_directory: ~/project 8 | 9 | commands: 10 | attach_project: 11 | steps: 12 | - attach_workspace: 13 | at: ~/project 14 | 15 | jobs: 16 | install-dependencies: 17 | executor: default 18 | steps: 19 | - checkout 20 | - attach_project 21 | - restore_cache: 22 | keys: 23 | - dependencies-{{ checksum "package.json" }} 24 | - dependencies- 25 | - restore_cache: 26 | keys: 27 | - dependencies-example-{{ checksum "example/package.json" }} 28 | - dependencies-example- 29 | - run: 30 | name: Install dependencies 31 | command: | 32 | yarn install --cwd example --frozen-lockfile 33 | yarn install --frozen-lockfile 34 | - save_cache: 35 | key: dependencies-{{ checksum "package.json" }} 36 | paths: node_modules 37 | - save_cache: 38 | key: dependencies-example-{{ checksum "example/package.json" }} 39 | paths: example/node_modules 40 | - persist_to_workspace: 41 | root: . 42 | paths: . 43 | 44 | lint: 45 | executor: default 46 | steps: 47 | - attach_project 48 | - run: 49 | name: Lint files 50 | command: | 51 | yarn lint 52 | 53 | typescript: 54 | executor: default 55 | steps: 56 | - attach_project 57 | - run: 58 | name: Typecheck files 59 | command: | 60 | yarn typescript 61 | 62 | unit-tests: 63 | executor: default 64 | steps: 65 | - attach_project 66 | - run: 67 | name: Run unit tests 68 | command: | 69 | yarn test --coverage 70 | - store_artifacts: 71 | path: coverage 72 | destination: coverage 73 | 74 | build-package: 75 | executor: default 76 | steps: 77 | - attach_project 78 | - run: 79 | name: Build package 80 | command: | 81 | yarn prepare 82 | 83 | workflows: 84 | build-and-test: 85 | jobs: 86 | - install-dependencies 87 | - lint: 88 | requires: 89 | - install-dependencies 90 | - typescript: 91 | requires: 92 | - install-dependencies 93 | - unit-tests: 94 | requires: 95 | - install-dependencies 96 | - build-package: 97 | requires: 98 | - install-dependencies 99 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | indent_style = space 10 | indent_size = 2 11 | 12 | end_of_line = lf 13 | charset = utf-8 14 | trim_trailing_whitespace = true 15 | insert_final_newline = true 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | # specific for windows script files 3 | *.bat text eol=crlf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IJ 33 | # 34 | .idea 35 | .gradle 36 | local.properties 37 | android.iml 38 | 39 | # Cocoapods 40 | # 41 | example/ios/Pods 42 | 43 | # node.js 44 | # 45 | node_modules/ 46 | npm-debug.log 47 | yarn-debug.log 48 | yarn-error.log 49 | 50 | # BUCK 51 | buck-out/ 52 | \.buckd/ 53 | android/app/libs 54 | android/keystores/debug.keystore 55 | 56 | # Expo 57 | .expo/* 58 | 59 | # generated by bob 60 | lib/ 61 | 62 | 63 | android/.cxx 64 | android/cmake-build-debug/ 65 | .cxx/ 66 | 67 | 68 | # Temporary files created by Metro to check the health of the file watcher 69 | example/.metro-health-check* 70 | example/ios/.xcode.env 71 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "cpp/leveldb"] 2 | path = cpp/leveldb 3 | url = https://github.com/google/leveldb.git 4 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | # Override Yarn command so we can automatically setup the repo on running `yarn` 2 | 3 | yarn-path "scripts/bootstrap.js" 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We want this community to be friendly and respectful to each other. Please follow it in all your interactions with the project. 4 | 5 | ## Development workflow 6 | 7 | To get started with the project, run `yarn` in the root directory to install the required dependencies for each package: 8 | 9 | ```sh 10 | # First, download leveldb. 11 | git submodule update --init --recursive 12 | 13 | # Then, install everything else, including Pods! 14 | yarn 15 | ``` 16 | 17 | While developing, you can run the [example app](/example/) to test your changes. 18 | 19 | To start the packager: 20 | 21 | ```sh 22 | yarn example start 23 | ``` 24 | 25 | To run the example app on iOS: 26 | 27 | ```sh 28 | yarn example ios 29 | ``` 30 | 31 | ```sh 32 | yarn example android 33 | ``` 34 | 35 | Make sure your code passes TypeScript and ESLint. Run the following to verify: 36 | 37 | ```sh 38 | yarn typescript 39 | yarn lint 40 | ``` 41 | 42 | To fix formatting errors, run the following: 43 | 44 | ```sh 45 | yarn lint --fix 46 | ``` 47 | 48 | Remember to add tests for your change if possible. Run the unit tests by: 49 | 50 | ```sh 51 | yarn test 52 | ``` 53 | 54 | To edit the Objective-C files, open `example/ios/LeveldbExample.xcworkspace` in XCode and find the source files at `Pods > Development Pods > react-native-leveldb`. 55 | 56 | To edit the Kotlin files, open `example/android` in Android studio and find the source files at `reactnativeleveldb` under `Android`. 57 | 58 | ### Commit message convention 59 | 60 | We follow the [conventional commits specification](https://www.conventionalcommits.org/en) for our commit messages: 61 | 62 | - `fix`: bug fixes, e.g. fix crash due to deprecated method. 63 | - `feat`: new features, e.g. add new method to the module. 64 | - `refactor`: code refactor, e.g. migrate from class components to hooks. 65 | - `docs`: changes into documentation, e.g. add usage example for the module.. 66 | - `test`: adding or updating tests, e.g. add integration tests using detox. 67 | - `chore`: tooling changes, e.g. change CI config. 68 | 69 | Our pre-commit hooks verify that your commit message matches this format when committing. 70 | 71 | ### Linting and tests 72 | 73 | [ESLint](https://eslint.org/), [Prettier](https://prettier.io/), [TypeScript](https://www.typescriptlang.org/) 74 | 75 | We use [TypeScript](https://www.typescriptlang.org/) for type checking, [ESLint](https://eslint.org/) with [Prettier](https://prettier.io/) for linting and formatting the code, and [Jest](https://jestjs.io/) for testing. 76 | 77 | Our pre-commit hooks verify that the linter and tests pass when committing. 78 | 79 | ### Scripts 80 | 81 | The `package.json` file contains various scripts for common tasks: 82 | 83 | - `yarn bootstrap`: setup project by installing all dependencies and pods. 84 | - `yarn typescript`: type-check files with TypeScript. 85 | - `yarn lint`: lint files with ESLint. 86 | - `yarn test`: run unit tests with Jest. 87 | - `yarn example start`: start the Metro server for the example app. 88 | - `yarn example android`: run the example app on Android. 89 | - `yarn example ios`: run the example app on iOS. 90 | 91 | ### Sending a pull request 92 | 93 | > **Working on your first pull request?** You can learn how from this _free_ series: [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github). 94 | 95 | When you're sending a pull request: 96 | 97 | - Prefer small pull requests focused on one change. 98 | - Verify that linters and tests are passing. 99 | - Review the documentation to make sure it looks good. 100 | - Follow the pull request template when opening a pull request. 101 | - For pull requests that change the API or implementation, discuss with maintainers first by opening an issue. 102 | 103 | ## Code of Conduct 104 | 105 | ### Our Pledge 106 | 107 | We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 108 | 109 | We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. 110 | 111 | ### Our Standards 112 | 113 | Examples of behavior that contributes to a positive environment for our community include: 114 | 115 | - Demonstrating empathy and kindness toward other people 116 | - Being respectful of differing opinions, viewpoints, and experiences 117 | - Giving and gracefully accepting constructive feedback 118 | - Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience 119 | - Focusing on what is best not just for us as individuals, but for the overall community 120 | 121 | Examples of unacceptable behavior include: 122 | 123 | - The use of sexualized language or imagery, and sexual attention or 124 | advances of any kind 125 | - Trolling, insulting or derogatory comments, and personal or political attacks 126 | - Public or private harassment 127 | - Publishing others' private information, such as a physical or email 128 | address, without their explicit permission 129 | - Other conduct which could reasonably be considered inappropriate in a 130 | professional setting 131 | 132 | ### Enforcement Responsibilities 133 | 134 | Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. 135 | 136 | Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. 137 | 138 | ### Scope 139 | 140 | This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. 141 | 142 | ### Enforcement 143 | 144 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [INSERT CONTACT METHOD]. All complaints will be reviewed and investigated promptly and fairly. 145 | 146 | All community leaders are obligated to respect the privacy and security of the reporter of any incident. 147 | 148 | ### Enforcement Guidelines 149 | 150 | Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: 151 | 152 | #### 1. Correction 153 | 154 | **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. 155 | 156 | **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. 157 | 158 | #### 2. Warning 159 | 160 | **Community Impact**: A violation through a single incident or series of actions. 161 | 162 | **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. 163 | 164 | #### 3. Temporary Ban 165 | 166 | **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. 167 | 168 | **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. 169 | 170 | #### 4. Permanent Ban 171 | 172 | **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. 173 | 174 | **Consequence**: A permanent ban from any sort of public interaction within the community. 175 | 176 | ### Attribution 177 | 178 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, 179 | available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 180 | 181 | Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). 182 | 183 | [homepage]: https://www.contributor-covenant.org 184 | 185 | For answers to common questions about this code of conduct, see the FAQ at 186 | https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. 187 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 GreenTriangle 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-leveldb 2 | Sponsored by ![GreenTriangle](https://www.green-triangle.com/wp-content/uploads/2021/04/Logo-300x66.png) 3 | 4 | Superfast React Native bindings for LevelDB: 5 | * 2-7x faster than AsyncStorage or react-native-sqlite-storage - try the benchmarks under example/! 6 | * completely synchronous, blocking API (even on slow devices, a single read or write takes 0.1ms) 7 | * use it with Flatbuffers to turbo charge your app - support for binary data via ArrayBuffers 8 | 9 | ## Installation 10 | 11 | ```sh 12 | yarn add react-native-leveldb 13 | cd ios && pod install 14 | ``` 15 | 16 | ## Usage 17 | 18 | ```ts 19 | import {LevelDB} from "react-native-leveldb"; 20 | 21 | // Open a potentially new database. 22 | const name = 'example.db'; 23 | const createIfMissing = true; 24 | const errorIfExists = false; 25 | 26 | const db = new LevelDB(name, createIfMissing, errorIfExists); 27 | 28 | // Insert something into the database. Note that the key and the 29 | // value can either be strings or ArrayBuffers. 30 | 31 | // Strings are read & written in utf8. 32 | db.put('key', 'value'); 33 | 34 | // You can also use ArrayBuffers as input, containing binary data. 35 | const key = new Uint8Array([1, 2, 3]); 36 | const value = new Uint32Array([654321]); 37 | db.put(key.buffer, value.buffer); 38 | 39 | // Get values as string or as an ArrayBuffer (useful for binary data). 40 | const readStringValue = db.getStr('key'); 41 | const readBufferValue = new Uint32Array(db.getBuf(key.buffer)!); 42 | console.log(readStringValue, readBufferValue); // logs: value [654321] 43 | 44 | // Iterate over a range of values (here, from key "key" to the end.) 45 | let iter = db.newIterator(); 46 | for (iter.seek('key'); iter.valid(); iter.next()) { 47 | // There are also *Buf version to access iterators' keys & values. 48 | console.log(`iterating: "${iter.keyStr()}" / "${iter.valueStr()}"`); 49 | } 50 | 51 | // You need to close iterators when you are done with them. 52 | // Iterators will throw an error if used after this. 53 | iter.close(); 54 | 55 | db.close(); // Same for databases. 56 | 57 | ``` 58 | 59 | ## Contributing 60 | 61 | See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. 62 | 63 | ## License 64 | 65 | MIT 66 | -------------------------------------------------------------------------------- /android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | reactnativeleveldb 4 | Project android_ created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.buildship.core.gradleprojectnature 22 | 23 | 24 | 25 | 1680772520395 26 | 27 | 30 28 | 29 | org.eclipse.core.resources.regexFilterMatcher 30 | node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | arguments=--init-script /home/undefined/.config/Code/User/globalStorage/redhat.java/1.16.0/config_linux/org.eclipse.osgi/51/0/.cp/gradle/init/init.gradle --init-script /home/undefined/.config/Code/User/globalStorage/redhat.java/1.16.0/config_linux/org.eclipse.osgi/51/0/.cp/gradle/protobuf/init.gradle 2 | auto.sync=false 3 | build.scans.enabled=false 4 | connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(7.4.2)) 5 | connection.project.dir= 6 | eclipse.preferences.version=1 7 | gradle.user.home= 8 | java.home=/usr/lib/jvm/java-11-openjdk-amd64 9 | jvm.arguments= 10 | offline.mode=false 11 | override.workspace.settings=true 12 | show.console.view=true 13 | show.executions.view=true 14 | -------------------------------------------------------------------------------- /android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9.0) 2 | project(reactnativeleveldb) 3 | 4 | set (PACKAGE_NAME "react-native-leveldb") 5 | set (BUILD_DIR ${CMAKE_SOURCE_DIR}/build) 6 | 7 | set (LEVELDB_BUILD_TESTS OFF CACHE INTERNAL "Really don't build LevelDB tests") # FORCE implied by INTERNAL 8 | set (LEVELDB_BUILD_BENCHMARKS OFF CACHE INTERNAL "Really don't build LevelDB benchmarks") 9 | set (LEVELDB_INSTALL OFF CACHE INTERNAL "Really don't install LevelDB") 10 | 11 | add_subdirectory(../cpp/leveldb leveldb) 12 | 13 | include_directories( 14 | ../cpp/leveldb 15 | "${NODE_MODULES_DIR}/react-native/React" 16 | "${NODE_MODULES_DIR}/react-native/React/Base" 17 | "${NODE_MODULES_DIR}/react-native/ReactCommon/jsi" 18 | ) 19 | 20 | add_library(reactnativeleveldb # Library name 21 | SHARED # Sets the library as a shared library. 22 | ../cpp/react-native-leveldb.cpp 23 | cpp-adapter.cpp 24 | ) 25 | 26 | set_target_properties( 27 | reactnativeleveldb PROPERTIES 28 | CXX_STANDARD 14 29 | CXX_EXTENSIONS OFF 30 | POSITION_INDEPENDENT_CODE ON 31 | ) 32 | 33 | file (GLOB LIBRN_DIR "${BUILD_DIR}/react-native-0*/jni/${ANDROID_ABI}") 34 | 35 | find_library( 36 | log-lib 37 | log 38 | ) 39 | find_library( 40 | JSI_LIB 41 | jsi 42 | PATHS ${LIBRN_DIR} 43 | NO_CMAKE_FIND_ROOT_PATH 44 | ) 45 | find_library( 46 | REACT_NATIVE_JNI_LIB 47 | reactnativejni 48 | PATHS ${LIBRN_DIR} 49 | NO_CMAKE_FIND_ROOT_PATH 50 | ) 51 | 52 | find_package(ReactAndroid REQUIRED CONFIG) 53 | 54 | target_link_libraries( 55 | reactnativeleveldb 56 | leveldb 57 | ${log-lib} 58 | # ${JSI_LIB} 59 | # ${REACT_NATIVE_JNI_LIB} 60 | ReactAndroid::jsi # <-- JSI 61 | android 62 | ) 63 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { 4 | url 'https://plugins.gradle.org/m2/' 5 | } 6 | mavenCentral() 7 | google() 8 | } 9 | 10 | dependencies { 11 | classpath('com.android.tools.build:gradle:7.2.2') 12 | } 13 | } 14 | 15 | def resolveBuildType() { 16 | Gradle gradle = getGradle() 17 | String tskReqStr = gradle.getStartParameter().getTaskRequests()['args'].toString() 18 | 19 | return tskReqStr.contains('Release') ? 'release' : 'debug' 20 | } 21 | 22 | def isNewArchitectureEnabled() { 23 | // To opt-in for the New Architecture, you can either: 24 | // - Set `newArchEnabled` to true inside the `gradle.properties` file 25 | // - Invoke gradle with `-newArchEnabled=true` 26 | // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true` 27 | return project.hasProperty('newArchEnabled') && project.newArchEnabled == 'true' 28 | } 29 | 30 | if (isNewArchitectureEnabled()) { 31 | apply plugin: 'com.facebook.react' 32 | } 33 | apply plugin: 'com.android.library' 34 | 35 | def safeExtGet(prop, fallback) { 36 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 37 | } 38 | 39 | def reactNativeArchitectures() { 40 | def value = project.getProperties().get('reactNativeArchitectures') 41 | return value ? value.split(',') : ['armeabi-v7a', 'x86', 'x86_64', 'arm64-v8a'] 42 | } 43 | 44 | repositories { 45 | mavenCentral() 46 | } 47 | 48 | android { 49 | compileSdkVersion safeExtGet('compileSdkVersion', 28) 50 | def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION 51 | if (agpVersion.tokenize('.')[0].toInteger() >= 7) { 52 | namespace "com.reactnativeleveldb" 53 | buildFeatures { 54 | buildConfig true 55 | } 56 | } 57 | 58 | // Used to override the NDK path/version on internal CI or by allowing 59 | // users to customize the NDK path/version from their root project (e.g. for M1 support) 60 | if (rootProject.hasProperty('ndkPath')) { 61 | ndkPath rootProject.ext.ndkPath 62 | } 63 | if (rootProject.hasProperty('ndkVersion')) { 64 | ndkVersion rootProject.ext.ndkVersion 65 | } 66 | 67 | buildFeatures { 68 | prefab true 69 | } 70 | 71 | defaultConfig { 72 | minSdkVersion safeExtGet('minSdkVersion', 16) 73 | targetSdkVersion safeExtGet('targetSdkVersion', 28) 74 | versionCode 1 75 | versionName '1.0' 76 | buildConfigField 'boolean', 'IS_NEW_ARCHITECTURE_ENABLED', isNewArchitectureEnabled().toString() 77 | externalNativeBuild { 78 | cmake { 79 | cppFlags '-O2 -frtti -fexceptions -Wall -Wno-unused-variable -Wno-unused-but-set-variable -fstack-protector-all' 80 | arguments '-DANDROID_STL=c++_shared' 81 | abiFilters(*reactNativeArchitectures()) 82 | } 83 | } 84 | } 85 | 86 | compileOptions { 87 | sourceCompatibility JavaVersion.VERSION_1_8 88 | targetCompatibility JavaVersion.VERSION_1_8 89 | } 90 | 91 | externalNativeBuild { 92 | cmake { 93 | path 'CMakeLists.txt' 94 | } 95 | } 96 | packagingOptions { 97 | doNotStrip resolveBuildType() == 'debug' ? '**/**/*.so' : '' 98 | excludes = [ 99 | 'META-INF', 100 | 'META-INF/**', 101 | '**/libjsi.so', 102 | '**/libc++_shared.so' 103 | ] 104 | } 105 | } 106 | 107 | dependencies { 108 | //noinspection GradleDynamicVersion 109 | implementation 'com.facebook.react:react-android:+' 110 | } 111 | 112 | // Resolves "LOCAL_SRC_FILES points to a missing file, Check that libfb.so exists or that its path is correct". 113 | tasks.whenTaskAdded { task -> 114 | if (task.name.contains('configureCMakeDebug')) { 115 | rootProject.getTasksByName('packageReactNdkDebugLibs', true).forEach { 116 | task.dependsOn(it) 117 | } 118 | } 119 | // We want to add a dependency for both configureCMakeRelease and configureCMakeRelWithDebInfo 120 | if (task.name.contains('configureCMakeRel')) { 121 | rootProject.getTasksByName('packageReactNdkReleaseLibs', true).forEach { 122 | task.dependsOn(it) 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /android/cpp-adapter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../cpp/react-native-leveldb.h" 3 | #include 4 | 5 | extern "C" 6 | JNIEXPORT void JNICALL 7 | Java_com_reactnativeleveldb_LeveldbModule_initialize(JNIEnv* env, jclass clazz, jlong jsiPtr, jstring docDir) { 8 | const char *cstr = env->GetStringUTFChars(docDir, NULL); 9 | std::string str = std::string(cstr); 10 | env->ReleaseStringUTFChars(docDir, cstr); 11 | __android_log_print(ANDROID_LOG_VERBOSE, "react-native-leveldb", "Initializing react-native-leveldb with document dir %s", str.c_str()); 12 | installLeveldb(*reinterpret_cast(jsiPtr), std::string(str)); 13 | } 14 | 15 | extern "C" 16 | JNIEXPORT void JNICALL 17 | Java_com_reactnativeleveldb_LeveldbModule_destruct(JNIEnv* env, jclass clazz) { 18 | cleanupLeveldb(); 19 | } -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | Leveldb_kotlinVersion=1.7.0 2 | Leveldb_minSdkVersion=21 3 | Leveldb_targetSdkVersion=31 4 | Leveldb_compileSdkVersion=31 5 | Leveldb_ndkversion=21.4.7075529 6 | android.useAndroidX=true 7 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactnativeleveldb/LeveldbModule.java: -------------------------------------------------------------------------------- 1 | package com.reactnativeleveldb; 2 | 3 | import androidx.annotation.NonNull; 4 | import com.facebook.react.bridge.JavaScriptContextHolder; 5 | import com.facebook.react.bridge.Promise; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 8 | import android.util.Log; 9 | import com.facebook.react.bridge.ReactMethod; 10 | import com.facebook.react.module.annotations.ReactModule; 11 | 12 | @ReactModule(name = LeveldbModule.NAME) 13 | public class LeveldbModule extends ReactContextBaseJavaModule { 14 | public static final String NAME = "Leveldb"; 15 | 16 | public LeveldbModule(ReactApplicationContext reactContext) { 17 | super(reactContext); 18 | } 19 | 20 | @Override 21 | @NonNull 22 | public String getName() { 23 | return NAME; 24 | } 25 | 26 | static { 27 | try { 28 | Log.i(NAME, "Loading C++ library..."); 29 | System.loadLibrary("reactnativeleveldb"); 30 | } catch (Exception ignored) { 31 | } 32 | } 33 | 34 | @ReactMethod(isBlockingSynchronousMethod = true) 35 | public boolean install() { 36 | try { 37 | JavaScriptContextHolder jsContext = getReactApplicationContext().getJavaScriptContextHolder(); 38 | String directory = getReactApplicationContext().getFilesDir().getAbsolutePath(); 39 | Log.i(NAME, "Initializing leveldb with directory " + directory); 40 | LeveldbModule.initialize(jsContext.get(), directory); 41 | Log.i(NAME, "Successfully installed!"); 42 | return true; 43 | } catch (Exception exception) { 44 | Log.e(NAME, "Failed to install JSI Bindings!", exception); 45 | return false; 46 | } 47 | } 48 | 49 | private static native void initialize(long jsiPtr, String docDir); 50 | private static native void destruct(); 51 | 52 | @Override 53 | public void onCatalystInstanceDestroy() { 54 | Log.i("Leveldb", "Closing all leveldb iterators and instances"); 55 | LeveldbModule.destruct(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactnativeleveldb/LeveldbPackage.java: -------------------------------------------------------------------------------- 1 | package com.reactnativeleveldb; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import com.facebook.react.ReactPackage; 6 | import com.facebook.react.bridge.NativeModule; 7 | import com.facebook.react.bridge.ReactApplicationContext; 8 | import com.facebook.react.uimanager.ViewManager; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class LeveldbPackage implements ReactPackage { 15 | @NonNull 16 | @Override 17 | public List createNativeModules(@NonNull ReactApplicationContext reactContext) { 18 | List modules = new ArrayList<>(); 19 | modules.add(new LeveldbModule(reactContext)); 20 | return modules; 21 | } 22 | 23 | @NonNull 24 | @Override 25 | public List createViewManagers(@NonNull ReactApplicationContext reactContext) { 26 | return Collections.emptyList(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /cpp/react-native-leveldb.cpp: -------------------------------------------------------------------------------- 1 | #import "react-native-leveldb.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #import 7 | #import 8 | 9 | using namespace facebook; 10 | 11 | 12 | // TODO(savv): consider re-using unique_ptrs, if they are empty. 13 | std::vector> dbs; 14 | std::vector> iterators; 15 | 16 | // Returns false if the passed value is not a string or an ArrayBuffer. 17 | bool valueToString(jsi::Runtime& runtime, const jsi::Value& value, std::string* str) { 18 | if (value.isString()) { 19 | *str = value.asString(runtime).utf8(runtime); 20 | return true; 21 | } 22 | 23 | if (value.isObject()) { 24 | auto obj = value.asObject(runtime); 25 | if (!obj.isArrayBuffer(runtime)) { 26 | return false; 27 | } 28 | auto buf = obj.getArrayBuffer(runtime); 29 | *str = std::string((char*)buf.data(runtime), buf.size(runtime)); 30 | return true; 31 | } 32 | 33 | return false; 34 | } 35 | 36 | leveldb::DB* valueToDb(const jsi::Value& value, std::string* err) { 37 | if (!value.isNumber()) { 38 | *err = "valueToDb/param-not-a-number"; 39 | return nullptr; 40 | } 41 | int idx = (int)value.getNumber(); 42 | if (idx < 0 || idx >= dbs.size()) { 43 | *err = "valueToDb/idx-out-of-range"; 44 | return nullptr; 45 | } 46 | if (!dbs[idx].get()) { 47 | *err = "valueToDb/db-closed"; 48 | return nullptr; 49 | } 50 | 51 | return dbs[idx].get(); 52 | } 53 | 54 | leveldb::Iterator* valueToIterator(const jsi::Value& value) { 55 | if (!value.isNumber()) { 56 | return nullptr; 57 | } 58 | int idx = (int)value.getNumber(); 59 | if (idx < 0 || idx >= iterators.size()) { 60 | return nullptr; 61 | } 62 | 63 | return iterators[idx].get(); 64 | } 65 | 66 | void installLeveldb(jsi::Runtime& jsiRuntime, std::string documentDir) { 67 | if (documentDir[documentDir.length() - 1] != '/') { 68 | documentDir += '/'; 69 | } 70 | std::cout << "Initializing react-native-leveldb with document dir \"" << documentDir << "\"" << "\n"; 71 | 72 | auto leveldbOpen = jsi::Function::createFromHostFunction( 73 | jsiRuntime, 74 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbOpen"), 75 | 3, // db path, create_if_missing, error_if_exists 76 | [documentDir](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 77 | if (!arguments[0].isString() || !arguments[1].isBool() || !arguments[2].isBool()) { 78 | throw jsi::JSError(runtime, "leveldbOpen/invalid-params"); 79 | } 80 | 81 | leveldb::Options options; 82 | std::string path = documentDir + arguments[0].getString(runtime).utf8(runtime); 83 | options.create_if_missing = arguments[1].getBool(); 84 | options.error_if_exists = arguments[2].getBool(); 85 | leveldb::DB* db; 86 | leveldb::Status status = leveldb::DB::Open(options, path, &db); 87 | dbs.push_back(std::unique_ptr{db}); 88 | int idx = (int)dbs.size() - 1; 89 | 90 | if (!status.ok()) { 91 | dbs[idx].reset(); 92 | throw jsi::JSError(runtime, "leveldbOpen/" + status.ToString()); 93 | } 94 | 95 | return jsi::Value(idx); 96 | } 97 | ); 98 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbOpen", std::move(leveldbOpen)); 99 | 100 | auto leveldbDestroy = jsi::Function::createFromHostFunction( 101 | jsiRuntime, 102 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbDestroy"), 103 | 1, // db path 104 | [documentDir](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 105 | if (!arguments[0].isString()) { 106 | throw jsi::JSError(runtime, "leveldbDestroy/invalid-params"); 107 | } 108 | 109 | leveldb::Options options; 110 | std::string path = documentDir + arguments[0].getString(runtime).utf8(runtime); 111 | leveldb::Status status = leveldb::DestroyDB(path, options); 112 | if (!status.ok()) { 113 | throw jsi::JSError(runtime, "leveldbDestroy/" + status.ToString()); 114 | } 115 | 116 | return nullptr; 117 | } 118 | ); 119 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbDestroy", std::move(leveldbDestroy)); 120 | 121 | auto leveldbClose = jsi::Function::createFromHostFunction( 122 | jsiRuntime, 123 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbClose"), 124 | 1, // dbs index 125 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 126 | if (!arguments[0].isNumber()) { 127 | throw jsi::JSError(runtime, "leveldbClose/invalid-params"); 128 | } 129 | int idx = (int)arguments[0].getNumber(); 130 | if (idx < 0 || idx >= dbs.size() || !dbs[idx].get()) { 131 | throw jsi::JSError(runtime, "leveldbClose/db-idx-out-of-bounds"); 132 | } 133 | 134 | dbs[idx].reset(); 135 | return nullptr; 136 | } 137 | ); 138 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbClose", std::move(leveldbClose)); 139 | 140 | auto leveldbPut = jsi::Function::createFromHostFunction( 141 | jsiRuntime, 142 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbPut"), 143 | 3, // dbs index, key, value 144 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 145 | std::string key, value; 146 | std::string dbErr; 147 | leveldb::DB* db = valueToDb(arguments[0], &dbErr); 148 | if (!db) { 149 | throw jsi::JSError(runtime, "leveldbPut/" + dbErr); 150 | } 151 | if (!valueToString(runtime, arguments[1], &key) || !valueToString(runtime, arguments[2], &value)) { 152 | throw jsi::JSError(runtime, "leveldbPut/invalid-params"); 153 | } 154 | 155 | auto status = db->Put(leveldb::WriteOptions(), key, value); 156 | 157 | if (!status.ok()) { 158 | throw jsi::JSError(runtime, "leveldbPut/" + status.ToString()); 159 | } 160 | 161 | return nullptr; 162 | } 163 | ); 164 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbPut", std::move(leveldbPut)); 165 | 166 | auto leveldbDelete = jsi::Function::createFromHostFunction( 167 | jsiRuntime, 168 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbDelete"), 169 | 2, // dbs index, key 170 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 171 | std::string key; 172 | std::string dbErr; 173 | leveldb::DB* db = valueToDb(arguments[0], &dbErr); 174 | if (!db) { 175 | throw jsi::JSError(runtime, "leveldbDelete/" + dbErr); 176 | } 177 | if (!valueToString(runtime, arguments[1], &key)) { 178 | throw jsi::JSError(runtime, "leveldbDelete/invalid-params"); 179 | } 180 | 181 | auto status = db->Delete(leveldb::WriteOptions(), key); 182 | 183 | if (status.ok() || status.IsNotFound()) { 184 | return nullptr; 185 | } else { 186 | throw jsi::JSError(runtime, "leveldbDelete/" + status.ToString()); 187 | } 188 | } 189 | ); 190 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbDelete", std::move(leveldbDelete)); 191 | 192 | auto leveldbNewIterator = jsi::Function::createFromHostFunction( 193 | jsiRuntime, 194 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbNewIterator"), 195 | 1, // index into dbs vector 196 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 197 | std::string dbErr; 198 | leveldb::DB* db = valueToDb(arguments[0], &dbErr); 199 | if (!db) { 200 | throw jsi::JSError(runtime, "leveldbNewIterator/" + dbErr); 201 | } 202 | iterators.push_back(std::unique_ptr{db->NewIterator(leveldb::ReadOptions())}); 203 | return jsi::Value((int)iterators.size() - 1); 204 | } 205 | ); 206 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbNewIterator", std::move(leveldbNewIterator)); 207 | 208 | auto leveldbIteratorSeekToFirst = jsi::Function::createFromHostFunction( 209 | jsiRuntime, 210 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorSeekToFirst"), 211 | 1, // iterators index 212 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 213 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 214 | if (!iterator) { 215 | throw jsi::JSError(runtime, "leveldbIteratorSeekToFirst/invalid-params"); 216 | } 217 | iterator->SeekToFirst(); 218 | return nullptr; 219 | } 220 | ); 221 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorSeekToFirst", std::move(leveldbIteratorSeekToFirst)); 222 | 223 | auto leveldbIteratorSeekToLast = jsi::Function::createFromHostFunction( 224 | jsiRuntime, 225 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorSeekToLast"), 226 | 1, // iterators index 227 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 228 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 229 | if (!iterator) { 230 | throw jsi::JSError(runtime, "leveldbIteratorSeekToLast/invalid-params"); 231 | } 232 | iterator->SeekToLast(); 233 | return nullptr; 234 | } 235 | ); 236 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorSeekToLast", std::move(leveldbIteratorSeekToLast)); 237 | 238 | auto leveldbIteratorSeek = jsi::Function::createFromHostFunction( 239 | jsiRuntime, 240 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorSeek"), 241 | 2, // iterators index, seek target 242 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 243 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 244 | if (!iterator) { 245 | throw jsi::JSError(runtime, "leveldbIteratorSeek/invalid-params"); 246 | } 247 | 248 | std::string target; 249 | if (!valueToString(runtime, arguments[1], &target)) { 250 | throw jsi::JSError(runtime, "leveldbIteratorSeek/invalid-params"); 251 | } 252 | iterator->Seek(target); 253 | return nullptr; 254 | } 255 | ); 256 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorSeek", std::move(leveldbIteratorSeek)); 257 | 258 | auto leveldbIteratorValid = jsi::Function::createFromHostFunction( 259 | jsiRuntime, 260 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorValid"), 261 | 1, // iterators index 262 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 263 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 264 | if (!iterator) { 265 | throw jsi::JSError(runtime, "leveldbIteratorValid/invalid-params"); 266 | } 267 | return jsi::Value(iterator->Valid()); 268 | } 269 | ); 270 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorValid", std::move(leveldbIteratorValid)); 271 | 272 | auto leveldbIteratorPrev = jsi::Function::createFromHostFunction( 273 | jsiRuntime, 274 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorPrev"), 275 | 1, // iterators index 276 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 277 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 278 | if (!iterator) { 279 | throw jsi::JSError(runtime, "leveldbIteratorPrev/invalid-params"); 280 | } 281 | iterator->Prev(); 282 | return nullptr; 283 | } 284 | ); 285 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorPrev", std::move(leveldbIteratorPrev)); 286 | 287 | auto leveldbIteratorNext = jsi::Function::createFromHostFunction( 288 | jsiRuntime, 289 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorNext"), 290 | 1, // iterators index 291 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 292 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 293 | if (!iterator) { 294 | throw jsi::JSError(runtime, "leveldbIteratorNext/invalid-params"); 295 | } 296 | iterator->Next(); 297 | return nullptr; 298 | } 299 | ); 300 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorNext", std::move(leveldbIteratorNext)); 301 | 302 | auto leveldbIteratorDelete = jsi::Function::createFromHostFunction( 303 | jsiRuntime, 304 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorDelete"), 305 | 1, // iterators index 306 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 307 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 308 | if (!iterator) { 309 | throw jsi::JSError(runtime, "leveldbIteratorDelete/invalid-params"); 310 | } 311 | iterators[(int)arguments[0].getNumber()].reset(); 312 | return nullptr; 313 | } 314 | ); 315 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorDelete", std::move(leveldbIteratorDelete)); 316 | 317 | auto leveldbIteratorKeyStr = jsi::Function::createFromHostFunction( 318 | jsiRuntime, 319 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorKeyStr"), 320 | 1, // iterators index 321 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 322 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 323 | if (!iterator) { 324 | throw jsi::JSError(runtime, "leveldbIteratorKeyStr/invalid-params"); 325 | } 326 | return jsi::Value(jsi::String::createFromUtf8(runtime, iterator->key().ToString()));; 327 | } 328 | ); 329 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorKeyStr", std::move(leveldbIteratorKeyStr)); 330 | 331 | auto leveldbIteratorKeyCompare = jsi::Function::createFromHostFunction 332 | ( 333 | jsiRuntime, 334 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorKeyCompare"), 335 | 2, // iterators index, comparison target 336 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 337 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 338 | std::string target; 339 | if (!valueToString(runtime, arguments[1], &target)) { 340 | throw jsi::JSError(runtime, "leveldbIteratorKeyCompare/invalid-params"); 341 | } 342 | // Compare with input comparison string 343 | int comparisonResult = iterator->key().compare(target); 344 | if (!iterator) { 345 | throw jsi::JSError(runtime, "leveldbIteratorKeyCompare/invalid-params"); 346 | } 347 | return jsi::Value(comparisonResult); 348 | } 349 | ); 350 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorKeyCompare", std::move(leveldbIteratorKeyCompare)); 351 | 352 | auto leveldbIteratorValueStr = jsi::Function::createFromHostFunction( 353 | jsiRuntime, 354 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorValueStr"), 355 | 1, // iterators index 356 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 357 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 358 | if (!iterator) { 359 | throw jsi::JSError(runtime, "leveldbIteratorValueStr/invalid-params"); 360 | } 361 | return jsi::Value(jsi::String::createFromUtf8(runtime, iterator->value().ToString()));; 362 | } 363 | ); 364 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorValueStr", std::move(leveldbIteratorValueStr)); 365 | 366 | auto leveldbGetStr = jsi::Function::createFromHostFunction( 367 | jsiRuntime, 368 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbGetStr"), 369 | 2, // dbs index, key 370 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 371 | std::string dbErr; 372 | leveldb::DB* db = valueToDb(arguments[0], &dbErr); 373 | if (!db) { 374 | throw jsi::JSError(runtime, "leveldbGetStr/" + dbErr); 375 | } 376 | std::string key; 377 | if (!valueToString(runtime, arguments[1], &key)) { 378 | throw jsi::JSError(runtime, "leveldbGetStr/invalid-params"); 379 | } 380 | 381 | std::string value; 382 | auto status = db->Get(leveldb::ReadOptions(), key, &value); 383 | if (status.IsNotFound()) { 384 | return nullptr; 385 | } else if (!status.ok()) { 386 | throw jsi::JSError(runtime, "leveldbGetStr/" + status.ToString()); 387 | } 388 | return jsi::Value(jsi::String::createFromUtf8(runtime, value)); 389 | } 390 | ); 391 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbGetStr", std::move(leveldbGetStr)); 392 | 393 | auto leveldbIteratorKeyBuf = jsi::Function::createFromHostFunction( 394 | jsiRuntime, 395 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorKeyBuf"), 396 | 1, // iterators index 397 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 398 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 399 | if (!iterator) { 400 | throw jsi::JSError(runtime, "leveldbIteratorKeyBuf/invalid-params"); 401 | } 402 | std::string key = iterator->key().ToString(); 403 | 404 | jsi::Function arrayBufferCtor = runtime.global().getPropertyAsFunction(runtime, "ArrayBuffer"); 405 | jsi::Object o = arrayBufferCtor.callAsConstructor(runtime, (int)key.length()).getObject(runtime); 406 | jsi::ArrayBuffer buf = o.getArrayBuffer(runtime); 407 | memcpy(buf.data(runtime), key.c_str(), key.size()); 408 | return o; 409 | } 410 | ); 411 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorKeyBuf", std::move(leveldbIteratorKeyBuf)); 412 | 413 | auto leveldbIteratorValueBuf = jsi::Function::createFromHostFunction( 414 | jsiRuntime, 415 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbIteratorValueBuf"), 416 | 1, // iterators index 417 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 418 | leveldb::Iterator* iterator = valueToIterator(arguments[0]); 419 | if (!iterator) { 420 | throw jsi::JSError(runtime, "leveldbIteratorValueBuf/invalid-params"); 421 | } 422 | std::string value = iterator->value().ToString(); 423 | 424 | jsi::Function arrayBufferCtor = runtime.global().getPropertyAsFunction(runtime, "ArrayBuffer"); 425 | jsi::Object o = arrayBufferCtor.callAsConstructor(runtime, (int)value.length()).getObject(runtime); 426 | jsi::ArrayBuffer buf = o.getArrayBuffer(runtime); 427 | memcpy(buf.data(runtime), value.c_str(), value.size()); 428 | return o; 429 | } 430 | ); 431 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbIteratorValueBuf", std::move(leveldbIteratorValueBuf)); 432 | 433 | auto leveldbGetBuf = jsi::Function::createFromHostFunction( 434 | jsiRuntime, 435 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbGetBuf"), 436 | 2, // dbs index, key 437 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 438 | std::string dbErr; 439 | leveldb::DB* db = valueToDb(arguments[0], &dbErr); 440 | if (!db) { 441 | throw jsi::JSError(runtime, "leveldbGetBuf/" + dbErr); 442 | } 443 | std::string key; 444 | if (!valueToString(runtime, arguments[1], &key)) { 445 | throw jsi::JSError(runtime, "leveldbGetBuf/invalid-params"); 446 | } 447 | std::string value; 448 | auto status = db->Get(leveldb::ReadOptions(), key, &value); 449 | if (status.IsNotFound()) { 450 | return nullptr; 451 | } else if (!status.ok()) { 452 | throw jsi::JSError(runtime, "leveldbGetBuf/" + status.ToString()); 453 | } 454 | 455 | jsi::Function arrayBufferCtor = runtime.global().getPropertyAsFunction(runtime, "ArrayBuffer"); 456 | jsi::Object o = arrayBufferCtor.callAsConstructor(runtime, (int)value.length()).getObject(runtime); 457 | jsi::ArrayBuffer buf = o.getArrayBuffer(runtime); 458 | memcpy(buf.data(runtime), value.c_str(), value.size()); 459 | return o; 460 | } 461 | ); 462 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbGetBuf", std::move(leveldbGetBuf)); 463 | 464 | auto leveldbTestException = jsi::Function::createFromHostFunction( 465 | jsiRuntime, 466 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbTestException"), 467 | 0, 468 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 469 | throw jsi::JSError(runtime, "leveldbTestException"); 470 | return nullptr; 471 | } 472 | ); 473 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbTestException", std::move(leveldbTestException)); 474 | 475 | auto leveldbMerge = jsi::Function::createFromHostFunction( 476 | jsiRuntime, 477 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbMerge"), 478 | 3, // dbs index dest, dbs index src, batchBool 479 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 480 | std::string dbErr; 481 | leveldb::DB* dbDst = valueToDb(arguments[0], &dbErr); 482 | if (!dbDst) { 483 | throw jsi::JSError(runtime, "leveldbMerge/dst/" + dbErr); 484 | } 485 | leveldb::DB* dbSrc = valueToDb(arguments[1], &dbErr); 486 | if (!dbSrc) { 487 | throw jsi::JSError(runtime, "leveldbMerge/src/" + dbErr); 488 | } 489 | if (!arguments[2].isBool()) { 490 | throw jsi::JSError(runtime, "leveldbMerge/batchMerge-param-not-a-boolean"); 491 | } 492 | bool batchMerge = (bool)arguments[2].getBool(); 493 | 494 | leveldb::WriteBatch batch; 495 | std::unique_ptr itSrc(dbSrc->NewIterator(leveldb::ReadOptions())); 496 | for (itSrc->SeekToFirst(); itSrc->Valid(); itSrc->Next()) { 497 | if (batchMerge) { 498 | batch.Put(itSrc->key(), itSrc->value()); 499 | } else { 500 | dbDst->Put(leveldb::WriteOptions(), itSrc->key(), itSrc->value()); 501 | } 502 | } 503 | 504 | if (!itSrc->status().ok()) { 505 | throw jsi::JSError(runtime, "leveldbMerge/" + itSrc->status().ToString()); 506 | } 507 | 508 | if (batchMerge) { 509 | dbDst->Write(leveldb::WriteOptions(), &batch); 510 | } 511 | 512 | return nullptr; 513 | } 514 | ); 515 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbMerge", std::move(leveldbMerge)); 516 | 517 | auto leveldbReadFileBuf = jsi::Function::createFromHostFunction( 518 | jsiRuntime, 519 | jsi::PropNameID::forAscii(jsiRuntime, "leveldbReadFileBuf"), 520 | 3, // path, pos, len 521 | [](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value { 522 | std::string path; 523 | if (!valueToString(runtime, arguments[0], &path) || !arguments[1].isNumber() || !arguments[2].isNumber()) { 524 | throw jsi::JSError(runtime, "leveldbReadFileBuf/invalid-params"); 525 | } 526 | int pos = (int)arguments[1].getNumber(), len = (int)arguments[2].getNumber(); 527 | std::ifstream file(path, std::ios::in | std::ios::binary); 528 | if (!file || !file.is_open()) { 529 | throw jsi::JSError(runtime, "leveldbReadFileBuf/open-error/" + std::string(std::strerror(errno))); 530 | } 531 | 532 | file.seekg(0, std::ios::end); 533 | size_t file_size = file.tellg(); 534 | if (file_size < pos + len) { 535 | throw jsi::JSError(runtime, "leveldbReadFileBuf/invalid-len-plus-pos"); 536 | } 537 | 538 | file.seekg(pos, std::ios::beg); 539 | 540 | jsi::Function arrayBufferCtor = runtime.global().getPropertyAsFunction(runtime, "ArrayBuffer"); 541 | jsi::Object o = arrayBufferCtor.callAsConstructor(runtime, len).getObject(runtime); 542 | jsi::ArrayBuffer buf = o.getArrayBuffer(runtime); 543 | if (!file.read((char*)buf.data(runtime), len)) { 544 | throw jsi::JSError(runtime, "leveldbReadFileBuf/read-error/" + std::string(std::strerror(errno))); 545 | } 546 | 547 | return o; 548 | } 549 | ); 550 | jsiRuntime.global().setProperty(jsiRuntime, "leveldbReadFileBuf", std::move(leveldbReadFileBuf)); 551 | } 552 | 553 | void cleanupLeveldb() { 554 | iterators.clear(); 555 | dbs.clear(); 556 | } 557 | -------------------------------------------------------------------------------- /cpp/react-native-leveldb.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void installLeveldb(facebook::jsi::Runtime& jsiRuntime, std::string _documentDir); 4 | void cleanupLeveldb(); -------------------------------------------------------------------------------- /example/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | -------------------------------------------------------------------------------- /example/.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.5 2 | -------------------------------------------------------------------------------- /example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | gem 'cocoapods', '~> 1.13' 7 | gem 'activesupport', '>= 6.1.7.3', '< 7.1.0' 8 | -------------------------------------------------------------------------------- /example/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.6) 5 | rexml 6 | activesupport (6.1.7.6) 7 | concurrent-ruby (~> 1.0, >= 1.0.2) 8 | i18n (>= 1.6, < 2) 9 | minitest (>= 5.1) 10 | tzinfo (~> 2.0) 11 | zeitwerk (~> 2.3) 12 | addressable (2.8.5) 13 | public_suffix (>= 2.0.2, < 6.0) 14 | algoliasearch (1.27.5) 15 | httpclient (~> 2.8, >= 2.8.3) 16 | json (>= 1.5.1) 17 | atomos (0.1.3) 18 | claide (1.1.0) 19 | cocoapods (1.13.0) 20 | addressable (~> 2.8) 21 | claide (>= 1.0.2, < 2.0) 22 | cocoapods-core (= 1.13.0) 23 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 24 | cocoapods-downloader (>= 1.6.0, < 2.0) 25 | cocoapods-plugins (>= 1.0.0, < 2.0) 26 | cocoapods-search (>= 1.0.0, < 2.0) 27 | cocoapods-trunk (>= 1.6.0, < 2.0) 28 | cocoapods-try (>= 1.1.0, < 2.0) 29 | colored2 (~> 3.1) 30 | escape (~> 0.0.4) 31 | fourflusher (>= 2.3.0, < 3.0) 32 | gh_inspector (~> 1.0) 33 | molinillo (~> 0.8.0) 34 | nap (~> 1.0) 35 | ruby-macho (>= 2.3.0, < 3.0) 36 | xcodeproj (>= 1.23.0, < 2.0) 37 | cocoapods-core (1.13.0) 38 | activesupport (>= 5.0, < 8) 39 | addressable (~> 2.8) 40 | algoliasearch (~> 1.0) 41 | concurrent-ruby (~> 1.1) 42 | fuzzy_match (~> 2.0.4) 43 | nap (~> 1.0) 44 | netrc (~> 0.11) 45 | public_suffix (~> 4.0) 46 | typhoeus (~> 1.0) 47 | cocoapods-deintegrate (1.0.5) 48 | cocoapods-downloader (1.6.3) 49 | cocoapods-plugins (1.0.0) 50 | nap 51 | cocoapods-search (1.0.1) 52 | cocoapods-trunk (1.6.0) 53 | nap (>= 0.8, < 2.0) 54 | netrc (~> 0.11) 55 | cocoapods-try (1.2.0) 56 | colored2 (3.1.2) 57 | concurrent-ruby (1.2.2) 58 | escape (0.0.4) 59 | ethon (0.16.0) 60 | ffi (>= 1.15.0) 61 | ffi (1.16.3) 62 | fourflusher (2.3.1) 63 | fuzzy_match (2.0.4) 64 | gh_inspector (1.1.3) 65 | httpclient (2.8.3) 66 | i18n (1.14.1) 67 | concurrent-ruby (~> 1.0) 68 | json (2.6.3) 69 | minitest (5.20.0) 70 | molinillo (0.8.0) 71 | nanaimo (0.3.0) 72 | nap (1.1.0) 73 | netrc (0.11.0) 74 | public_suffix (4.0.7) 75 | rexml (3.2.6) 76 | ruby-macho (2.5.1) 77 | typhoeus (1.4.1) 78 | ethon (>= 0.9.0) 79 | tzinfo (2.0.6) 80 | concurrent-ruby (~> 1.0) 81 | xcodeproj (1.23.0) 82 | CFPropertyList (>= 2.3.3, < 4.0) 83 | atomos (~> 0.1.3) 84 | claide (>= 1.0.2, < 2.0) 85 | colored2 (~> 3.1) 86 | nanaimo (~> 0.3.0) 87 | rexml (~> 3.2.4) 88 | zeitwerk (2.6.12) 89 | 90 | PLATFORMS 91 | ruby 92 | 93 | DEPENDENCIES 94 | activesupport (>= 6.1.7.3, < 7.1.0) 95 | cocoapods (~> 1.13) 96 | 97 | RUBY VERSION 98 | ruby 2.7.4p191 99 | 100 | BUNDLED WITH 101 | 2.4.13 102 | -------------------------------------------------------------------------------- /example/android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | LeveldbExample 4 | Project android created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | 19 | 1680772520391 20 | 21 | 30 22 | 23 | org.eclipse.core.resources.regexFilterMatcher 24 | node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /example/android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | arguments=--init-script /home/undefined/.config/Code/User/globalStorage/redhat.java/1.16.0/config_linux/org.eclipse.osgi/51/0/.cp/gradle/init/init.gradle --init-script /home/undefined/.config/Code/User/globalStorage/redhat.java/1.16.0/config_linux/org.eclipse.osgi/51/0/.cp/gradle/protobuf/init.gradle 2 | auto.sync=false 3 | build.scans.enabled=false 4 | connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) 5 | connection.project.dir= 6 | eclipse.preferences.version=1 7 | gradle.user.home= 8 | java.home=/usr/lib/jvm/java-11-openjdk-amd64 9 | jvm.arguments= 10 | offline.mode=false 11 | override.workspace.settings=true 12 | show.console.view=true 13 | show.executions.view=true 14 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "com.facebook.react" 3 | 4 | 5 | 6 | /** 7 | * This is the configuration block to customize your React Native Android app. 8 | * By default you don't need to apply any configuration, just uncomment the lines you need. 9 | */ 10 | react { 11 | /* Folders */ 12 | // The root of your project, i.e. where "package.json" lives. Default is '..' 13 | // root = file("../") 14 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native 15 | // reactNativeDir = file("../node_modules/react-native") 16 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen 17 | // codegenDir = file("../node_modules/@react-native/codegen") 18 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js 19 | // cliFile = file("../node_modules/react-native/cli.js") 20 | 21 | /* Variants */ 22 | // The list of variants to that are debuggable. For those we're going to 23 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 24 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 25 | // debuggableVariants = ["liteDebug", "prodDebug"] 26 | 27 | /* Bundling */ 28 | // A list containing the node command and its flags. Default is just 'node'. 29 | // nodeExecutableAndArgs = ["node"] 30 | // 31 | // The command to run when bundling. By default is 'bundle' 32 | // bundleCommand = "ram-bundle" 33 | // 34 | // The path to the CLI configuration file. Default is empty. 35 | // bundleConfig = file(../rn-cli.config.js) 36 | // 37 | // The name of the generated asset file containing your JS bundle 38 | // bundleAssetName = "MyApplication.android.bundle" 39 | // 40 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 41 | // entryFile = file("../js/MyApplication.android.js") 42 | // 43 | // A list of extra flags to pass to the 'bundle' commands. 44 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 45 | // extraPackagerArgs = [] 46 | 47 | /* Hermes Commands */ 48 | // The hermes compiler command to run. By default it is 'hermesc' 49 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 50 | // 51 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 52 | // hermesFlags = ["-O", "-output-source-map"] 53 | } 54 | 55 | /** 56 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 57 | */ 58 | def enableProguardInReleaseBuilds = false 59 | 60 | /** 61 | * The preferred build flavor of JavaScriptCore (JSC) 62 | * 63 | * For example, to use the international variant, you can use: 64 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 65 | * 66 | * The international variant includes ICU i18n library and necessary data 67 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 68 | * give correct results when using with locales other than en-US. Note that 69 | * this variant is about 6MiB larger per architecture than default. 70 | */ 71 | def jscFlavor = 'org.webkit:android-jsc:+' 72 | 73 | android { 74 | ndkVersion rootProject.ext.ndkVersion 75 | 76 | compileSdkVersion rootProject.ext.compileSdkVersion 77 | 78 | namespace "com.example.reactnativeleveldb" 79 | defaultConfig { 80 | applicationId "com.example.reactnativeleveldb" 81 | minSdkVersion rootProject.ext.minSdkVersion 82 | targetSdkVersion rootProject.ext.targetSdkVersion 83 | versionCode 1 84 | versionName "1.0" 85 | } 86 | 87 | signingConfigs { 88 | debug { 89 | storeFile file('debug.keystore') 90 | storePassword 'android' 91 | keyAlias 'androiddebugkey' 92 | keyPassword 'android' 93 | } 94 | } 95 | buildTypes { 96 | debug { 97 | signingConfig signingConfigs.debug 98 | } 99 | release { 100 | // Caution! In production, you need to generate your own keystore file. 101 | // see https://reactnative.dev/docs/signed-apk-android. 102 | signingConfig signingConfigs.debug 103 | minifyEnabled enableProguardInReleaseBuilds 104 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 105 | } 106 | } 107 | } 108 | 109 | dependencies { 110 | // The version of react-native is set by the React Native Gradle Plugin 111 | implementation("com.facebook.react:react-android") 112 | 113 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") 114 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { 115 | exclude group:'com.squareup.okhttp3', module:'okhttp' 116 | } 117 | 118 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") 119 | if (hermesEnabled.toBoolean()) { 120 | implementation("com.facebook.react:hermes-android") 121 | } else { 122 | implementation jscFlavor 123 | } 124 | } 125 | 126 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 127 | -------------------------------------------------------------------------------- /example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/app/debug.keystore -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | -keep class com.facebook.hermes.unicode.** { *; } 13 | -keep class com.facebook.jni.** { *; } 14 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example/android/app/src/debug/java/com/example/reactnativeleveldb/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.example.reactnativeleveldb; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 21 | import com.facebook.react.ReactInstanceEventListener; 22 | import com.facebook.react.ReactInstanceManager; 23 | import com.facebook.react.bridge.ReactContext; 24 | import com.facebook.react.modules.network.NetworkingModule; 25 | import okhttp3.OkHttpClient; 26 | 27 | /** 28 | * Class responsible of loading Flipper inside your React Native application. This is the debug 29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup. 30 | */ 31 | public class ReactNativeFlipper { 32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 33 | if (FlipperUtils.shouldEnableFlipper(context)) { 34 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 35 | 36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 37 | client.addPlugin(new DatabasesFlipperPlugin(context)); 38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 39 | client.addPlugin(CrashReporterPlugin.getInstance()); 40 | 41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 42 | NetworkingModule.setCustomClientBuilder( 43 | new NetworkingModule.CustomClientBuilder() { 44 | @Override 45 | public void apply(OkHttpClient.Builder builder) { 46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 47 | } 48 | }); 49 | client.addPlugin(networkFlipperPlugin); 50 | client.start(); 51 | 52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 53 | // Hence we run if after all native modules have been initialized 54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 55 | if (reactContext == null) { 56 | reactInstanceManager.addReactInstanceEventListener( 57 | new ReactInstanceEventListener() { 58 | @Override 59 | public void onReactContextInitialized(ReactContext reactContext) { 60 | reactInstanceManager.removeReactInstanceEventListener(this); 61 | reactContext.runOnNativeModulesQueueThread( 62 | new Runnable() { 63 | @Override 64 | public void run() { 65 | client.addPlugin(new FrescoFlipperPlugin()); 66 | } 67 | }); 68 | } 69 | }); 70 | } else { 71 | client.addPlugin(new FrescoFlipperPlugin()); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/reactnativeleveldb/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.reactnativeleveldb; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate; 7 | 8 | public class MainActivity extends ReactActivity { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | @Override 15 | protected String getMainComponentName() { 16 | return "main"; 17 | } 18 | 19 | /** 20 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link 21 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React 22 | * (aka React 18) with two boolean flags. 23 | */ 24 | @Override 25 | protected ReactActivityDelegate createReactActivityDelegate() { 26 | return new DefaultReactActivityDelegate( 27 | this, 28 | getMainComponentName(), 29 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 30 | DefaultNewArchitectureEntryPoint.getFabricEnabled()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/reactnativeleveldb/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.reactnativeleveldb; 2 | 3 | import android.app.Application; 4 | import com.facebook.react.PackageList; 5 | import com.facebook.react.ReactApplication; 6 | import com.facebook.react.ReactNativeHost; 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 9 | import com.facebook.react.defaults.DefaultReactNativeHost; 10 | import com.facebook.soloader.SoLoader; 11 | import java.util.List; 12 | 13 | public class MainApplication extends Application implements ReactApplication { 14 | 15 | private final ReactNativeHost mReactNativeHost = 16 | new DefaultReactNativeHost(this) { 17 | @Override 18 | public boolean getUseDeveloperSupport() { 19 | return BuildConfig.DEBUG; 20 | } 21 | 22 | @Override 23 | protected List getPackages() { 24 | @SuppressWarnings("UnnecessaryLocalVariable") 25 | List packages = new PackageList(this).getPackages(); 26 | // Packages that cannot be autolinked yet can be added manually here, for example: 27 | // packages.add(new MyReactNativePackage()); 28 | return packages; 29 | } 30 | 31 | @Override 32 | protected String getJSMainModuleName() { 33 | return "index"; 34 | } 35 | 36 | @Override 37 | protected boolean isNewArchEnabled() { 38 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; 39 | } 40 | 41 | @Override 42 | protected Boolean isHermesEnabled() { 43 | return BuildConfig.IS_HERMES_ENABLED; 44 | } 45 | }; 46 | 47 | @Override 48 | public ReactNativeHost getReactNativeHost() { 49 | return mReactNativeHost; 50 | } 51 | 52 | @Override 53 | public void onCreate() { 54 | super.onCreate(); 55 | SoLoader.init(this, /* native exopackage */ false); 56 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 57 | // If you opted-in for the New Architecture, we load the native entry point for this app. 58 | DefaultNewArchitectureEntryPoint.load(); 59 | } 60 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/Android.mk: -------------------------------------------------------------------------------- 1 | THIS_DIR := $(call my-dir) 2 | 3 | include $(REACT_ANDROID_DIR)/Android-prebuilt.mk 4 | 5 | # If you wish to add a custom TurboModule or Fabric component in your app you 6 | # will have to include the following autogenerated makefile. 7 | # include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk 8 | include $(CLEAR_VARS) 9 | 10 | LOCAL_PATH := $(THIS_DIR) 11 | 12 | # You can customize the name of your application .so file here. 13 | LOCAL_MODULE := example_appmodules 14 | 15 | LOCAL_C_INCLUDES := $(LOCAL_PATH) 16 | LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) 17 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) 18 | 19 | # If you wish to add a custom TurboModule or Fabric component in your app you 20 | # will have to uncomment those lines to include the generated source 21 | # files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni) 22 | # 23 | # LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni 24 | # LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp) 25 | # LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni 26 | 27 | # Here you should add any native library you wish to depend on. 28 | LOCAL_SHARED_LIBRARIES := \ 29 | libfabricjni \ 30 | libfbjni \ 31 | libfolly_runtime \ 32 | libglog \ 33 | libjsi \ 34 | libreact_codegen_rncore \ 35 | libreact_debug \ 36 | libreact_nativemodule_core \ 37 | libreact_render_componentregistry \ 38 | libreact_render_core \ 39 | libreact_render_debug \ 40 | libreact_render_graphics \ 41 | librrc_view \ 42 | libruntimeexecutor \ 43 | libturbomodulejsijni \ 44 | libyoga 45 | 46 | LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall 47 | 48 | include $(BUILD_SHARED_LIBRARY) 49 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationModuleProvider.cpp: -------------------------------------------------------------------------------- 1 | #include "MainApplicationModuleProvider.h" 2 | 3 | #include 4 | 5 | namespace facebook { 6 | namespace react { 7 | 8 | std::shared_ptr MainApplicationModuleProvider( 9 | const std::string &moduleName, 10 | const JavaTurboModule::InitParams ¶ms) { 11 | // Here you can provide your own module provider for TurboModules coming from 12 | // either your application or from external libraries. The approach to follow 13 | // is similar to the following (for a library called `samplelibrary`: 14 | // 15 | // auto module = samplelibrary_ModuleProvider(moduleName, params); 16 | // if (module != nullptr) { 17 | // return module; 18 | // } 19 | // return rncore_ModuleProvider(moduleName, params); 20 | return rncore_ModuleProvider(moduleName, params); 21 | } 22 | 23 | } // namespace react 24 | } // namespace facebook 25 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp: -------------------------------------------------------------------------------- 1 | #include "MainApplicationTurboModuleManagerDelegate.h" 2 | #include "MainApplicationModuleProvider.h" 3 | 4 | namespace facebook { 5 | namespace react { 6 | 7 | jni::local_ref 8 | MainApplicationTurboModuleManagerDelegate::initHybrid( 9 | jni::alias_ref) { 10 | return makeCxxInstance(); 11 | } 12 | 13 | void MainApplicationTurboModuleManagerDelegate::registerNatives() { 14 | registerHybrid({ 15 | makeNativeMethod( 16 | "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid), 17 | makeNativeMethod( 18 | "canCreateTurboModule", 19 | MainApplicationTurboModuleManagerDelegate::canCreateTurboModule), 20 | }); 21 | } 22 | 23 | std::shared_ptr 24 | MainApplicationTurboModuleManagerDelegate::getTurboModule( 25 | const std::string &name, 26 | const std::shared_ptr &jsInvoker) { 27 | // Not implemented yet: provide pure-C++ NativeModules here. 28 | return nullptr; 29 | } 30 | 31 | std::shared_ptr 32 | MainApplicationTurboModuleManagerDelegate::getTurboModule( 33 | const std::string &name, 34 | const JavaTurboModule::InitParams ¶ms) { 35 | return MainApplicationModuleProvider(name, params); 36 | } 37 | 38 | bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule( 39 | const std::string &name) { 40 | return getTurboModule(name, nullptr) != nullptr || 41 | getTurboModule(name, {.moduleName = name}) != nullptr; 42 | } 43 | 44 | } // namespace react 45 | } // namespace facebook 46 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | namespace facebook { 8 | namespace react { 9 | 10 | class MainApplicationTurboModuleManagerDelegate 11 | : public jni::HybridClass< 12 | MainApplicationTurboModuleManagerDelegate, 13 | TurboModuleManagerDelegate> { 14 | public: 15 | // Adapt it to the package you used for your Java class. 16 | static constexpr auto kJavaDescriptor = 17 | "Lcom/example/reactnativeleveldb/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;"; 18 | 19 | static jni::local_ref initHybrid(jni::alias_ref); 20 | 21 | static void registerNatives(); 22 | 23 | std::shared_ptr getTurboModule( 24 | const std::string &name, 25 | const std::shared_ptr &jsInvoker) override; 26 | std::shared_ptr getTurboModule( 27 | const std::string &name, 28 | const JavaTurboModule::InitParams ¶ms) override; 29 | 30 | /** 31 | * Test-only method. Allows user to verify whether a TurboModule can be 32 | * created by instances of this class. 33 | */ 34 | bool canCreateTurboModule(const std::string &name); 35 | 36 | }; 37 | 38 | } // namespace react 39 | } // namespace facebook 40 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainComponentsRegistry.cpp: -------------------------------------------------------------------------------- 1 | #include "MainComponentsRegistry.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace facebook { 10 | namespace react { 11 | 12 | MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {} 13 | 14 | std::shared_ptr 15 | MainComponentsRegistry::sharedProviderRegistry() { 16 | auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); 17 | 18 | // Autolinked providers registered by RN CLI 19 | rncli_registerProviders(providerRegistry); 20 | 21 | // Custom Fabric Components go here. You can register custom 22 | // components coming from your App or from 3rd party libraries here. 23 | // 24 | // providerRegistry->add(concreteComponentDescriptorProvider< 25 | // AocViewerComponentDescriptor>()); 26 | return providerRegistry; 27 | } 28 | 29 | jni::local_ref 30 | MainComponentsRegistry::initHybrid( 31 | jni::alias_ref, 32 | ComponentFactory *delegate) { 33 | auto instance = makeCxxInstance(delegate); 34 | 35 | auto buildRegistryFunction = 36 | [](EventDispatcher::Weak const &eventDispatcher, 37 | ContextContainer::Shared const &contextContainer) 38 | -> ComponentDescriptorRegistry::Shared { 39 | auto registry = MainComponentsRegistry::sharedProviderRegistry() 40 | ->createComponentDescriptorRegistry( 41 | {eventDispatcher, contextContainer}); 42 | 43 | auto mutableRegistry = 44 | std::const_pointer_cast(registry); 45 | 46 | mutableRegistry->setFallbackComponentDescriptor( 47 | std::make_shared( 48 | ComponentDescriptorParameters{ 49 | eventDispatcher, contextContainer, nullptr})); 50 | 51 | return registry; 52 | }; 53 | 54 | delegate->buildRegistryFunction = buildRegistryFunction; 55 | return instance; 56 | } 57 | 58 | void MainComponentsRegistry::registerNatives() { 59 | registerHybrid({ 60 | makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid), 61 | }); 62 | } 63 | 64 | } // namespace react 65 | } // namespace facebook 66 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Leveldb Example 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/android/app/src/release/java/com/reactnativeleveldb/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.example.reactnativeleveldb; 8 | 9 | import android.content.Context; 10 | import com.facebook.react.ReactInstanceManager; 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. This is the release 14 | * flavor of it so it's empty as we don't want to load Flipper. 15 | */ 16 | public class ReactNativeFlipper { 17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 18 | // Do nothing as we don't want to initialize Flipper on Release. 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "33.0.0" 6 | minSdkVersion = 21 7 | compileSdkVersion = 33 8 | targetSdkVersion = 33 9 | 10 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. 11 | ndkVersion = "23.1.7779620" 12 | } 13 | repositories { 14 | google() 15 | mavenCentral() 16 | } 17 | dependencies { 18 | classpath("com.android.tools.build:gradle") 19 | classpath("com.facebook.react:react-native-gradle-plugin") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.182.0 29 | 30 | # Use this property to specify which architecture you want to build. 31 | # You can also override it from the CLI using 32 | # ./gradlew -PreactNativeArchitectures=x86_64 33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 34 | 35 | # Use this property to enable support to the new architecture. 36 | # This will allow you to use TurboModules and the Fabric render in 37 | # your application. You should enable this flag either if you want 38 | # to write custom TurboModules/Fabric components OR use libraries that 39 | # are providing them. 40 | newArchEnabled=true 41 | 42 | # Use this property to enable or disable the Hermes JS engine. 43 | # If set to false, you will be using JSC instead. 44 | hermesEnabled=true 45 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greentriangle/react-native-leveldb/8a3820ec850131f4a06dd0eae198ec3b7fd4308a/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /example/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 147 | # shellcheck disable=SC3045 148 | MAX_FD=$( ulimit -H -n ) || 149 | warn "Could not query maximum file descriptor limit" 150 | esac 151 | case $MAX_FD in #( 152 | '' | soft) :;; #( 153 | *) 154 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 155 | # shellcheck disable=SC3045 156 | ulimit -n "$MAX_FD" || 157 | warn "Could not set maximum file descriptor limit to $MAX_FD" 158 | esac 159 | fi 160 | 161 | # Collect all arguments for the java command, stacking in reverse order: 162 | # * args from the command line 163 | # * the main class name 164 | # * -classpath 165 | # * -D...appname settings 166 | # * --module-path (only if needed) 167 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 168 | 169 | # For Cygwin or MSYS, switch paths to Windows format before running java 170 | if "$cygwin" || "$msys" ; then 171 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 172 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 173 | 174 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 175 | 176 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 177 | for arg do 178 | if 179 | case $arg in #( 180 | -*) false ;; # don't mess with options #( 181 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 182 | [ -e "$t" ] ;; #( 183 | *) false ;; 184 | esac 185 | then 186 | arg=$( cygpath --path --ignore --mixed "$arg" ) 187 | fi 188 | # Roll the args list around exactly as many times as the number of 189 | # args, so each arg winds up back in the position where it started, but 190 | # possibly modified. 191 | # 192 | # NB: a `for` loop captures its iteration list before it begins, so 193 | # changing the positional parameters here affects neither the number of 194 | # iterations, nor the values presented in `arg`. 195 | shift # remove old arg 196 | set -- "$@" "$arg" # push replacement arg 197 | done 198 | fi 199 | 200 | # Collect all arguments for the java command; 201 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 202 | # shell script including quotes and variable substitutions, so put them in 203 | # double quotes to make sure that they get re-expanded; and 204 | # * put everything else in single quotes, so that it's not re-expanded. 205 | 206 | set -- \ 207 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 208 | -classpath "$CLASSPATH" \ 209 | org.gradle.wrapper.GradleWrapperMain \ 210 | "$@" 211 | 212 | # Stop when "xargs" is not available. 213 | if ! command -v xargs >/dev/null 2>&1 214 | then 215 | die "xargs is not available" 216 | fi 217 | 218 | # Use "xargs" to parse quoted args. 219 | # 220 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 221 | # 222 | # In Bash we could simply go: 223 | # 224 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 225 | # set -- "${ARGS[@]}" "$@" 226 | # 227 | # but POSIX shell has neither arrays nor command substitution, so instead we 228 | # post-process each arg (as a line of input to sed) to backslash-escape any 229 | # character that might be a shell metacharacter, then use eval to reverse 230 | # that process (while maintaining the separation between arguments), and wrap 231 | # the whole thing up as a single "set" statement. 232 | # 233 | # This will of course break if any of these variables contains a newline or 234 | # an unmatched quote. 235 | # 236 | 237 | eval "set -- $( 238 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 239 | xargs -n1 | 240 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 241 | tr '\n' ' ' 242 | )" '"$@"' 243 | 244 | exec "$JAVACMD" "$@" 245 | -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'LeveldbExample' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/@react-native/gradle-plugin') 5 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "main", 3 | "displayName": "Leveldb Example" 4 | } 5 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = { 5 | presets: ['module:metro-react-native-babel-preset'], 6 | plugins: [ 7 | [ 8 | 'module-resolver', 9 | { 10 | extensions: ['.tsx', '.ts', '.js', '.json'], 11 | alias: { 12 | [pak.name]: path.join(__dirname, '..', pak.source), 13 | }, 14 | }, 15 | ], 16 | ], 17 | }; 18 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './src/App'; 3 | import { name as appName } from './app.json'; 4 | 5 | AppRegistry.registerComponent(appName, () => App); 6 | -------------------------------------------------------------------------------- /example/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /example/ios/File.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // LeveldbExample 4 | // 5 | 6 | import Foundation 7 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0C80B921A6F3F58F76C31292 /* libPods-LeveldbExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-LeveldbExample.a */; }; 11 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 12 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 14 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXFileReference section */ 18 | 13B07F961A680F5B00A75B9A /* LeveldbExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LeveldbExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 19 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = LeveldbExample/AppDelegate.h; sourceTree = ""; }; 20 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = LeveldbExample/AppDelegate.mm; sourceTree = ""; }; 21 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = LeveldbExample/Images.xcassets; sourceTree = ""; }; 22 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = LeveldbExample/Info.plist; sourceTree = ""; }; 23 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = LeveldbExample/main.m; sourceTree = ""; }; 24 | 3B4392A12AC88292D35C810B /* Pods-LeveldbExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeveldbExample.debug.xcconfig"; path = "Target Support Files/Pods-LeveldbExample/Pods-LeveldbExample.debug.xcconfig"; sourceTree = ""; }; 25 | 5709B34CF0A7D63546082F79 /* Pods-LeveldbExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeveldbExample.release.xcconfig"; path = "Target Support Files/Pods-LeveldbExample/Pods-LeveldbExample.release.xcconfig"; sourceTree = ""; }; 26 | 5DCACB8F33CDC322A6C60F78 /* libPods-LeveldbExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LeveldbExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = LeveldbExample/LaunchScreen.storyboard; sourceTree = ""; }; 28 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | 0C80B921A6F3F58F76C31292 /* libPods-LeveldbExample.a in Frameworks */, 37 | ); 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXFrameworksBuildPhase section */ 41 | 42 | /* Begin PBXGroup section */ 43 | 13B07FAE1A68108700A75B9A /* LeveldbExample */ = { 44 | isa = PBXGroup; 45 | children = ( 46 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 47 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */, 48 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 49 | 13B07FB61A68108700A75B9A /* Info.plist */, 50 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, 51 | 13B07FB71A68108700A75B9A /* main.m */, 52 | ); 53 | name = LeveldbExample; 54 | sourceTree = ""; 55 | }; 56 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */, 60 | 5DCACB8F33CDC322A6C60F78 /* libPods-LeveldbExample.a */, 61 | ); 62 | name = Frameworks; 63 | sourceTree = ""; 64 | }; 65 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | ); 69 | name = Libraries; 70 | sourceTree = ""; 71 | }; 72 | 83CBB9F61A601CBA00E9B192 = { 73 | isa = PBXGroup; 74 | children = ( 75 | 13B07FAE1A68108700A75B9A /* LeveldbExample */, 76 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 77 | 83CBBA001A601CBA00E9B192 /* Products */, 78 | 2D16E6871FA4F8E400B85C8A /* Frameworks */, 79 | BBD78D7AC51CEA395F1C20DB /* Pods */, 80 | ); 81 | indentWidth = 2; 82 | sourceTree = ""; 83 | tabWidth = 2; 84 | usesTabs = 0; 85 | }; 86 | 83CBBA001A601CBA00E9B192 /* Products */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 13B07F961A680F5B00A75B9A /* LeveldbExample.app */, 90 | ); 91 | name = Products; 92 | sourceTree = ""; 93 | }; 94 | BBD78D7AC51CEA395F1C20DB /* Pods */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 3B4392A12AC88292D35C810B /* Pods-LeveldbExample.debug.xcconfig */, 98 | 5709B34CF0A7D63546082F79 /* Pods-LeveldbExample.release.xcconfig */, 99 | ); 100 | path = Pods; 101 | sourceTree = ""; 102 | }; 103 | /* End PBXGroup section */ 104 | 105 | /* Begin PBXNativeTarget section */ 106 | 13B07F861A680F5B00A75B9A /* LeveldbExample */ = { 107 | isa = PBXNativeTarget; 108 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "LeveldbExample" */; 109 | buildPhases = ( 110 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */, 111 | FD10A7F022414F080027D42C /* Start Packager */, 112 | 13B07F871A680F5B00A75B9A /* Sources */, 113 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 114 | 13B07F8E1A680F5B00A75B9A /* Resources */, 115 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 116 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */, 117 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */, 118 | ); 119 | buildRules = ( 120 | ); 121 | dependencies = ( 122 | ); 123 | name = LeveldbExample; 124 | productName = LeveldbExample; 125 | productReference = 13B07F961A680F5B00A75B9A /* LeveldbExample.app */; 126 | productType = "com.apple.product-type.application"; 127 | }; 128 | /* End PBXNativeTarget section */ 129 | 130 | /* Begin PBXProject section */ 131 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 132 | isa = PBXProject; 133 | attributes = { 134 | LastUpgradeCheck = 1210; 135 | TargetAttributes = { 136 | 13B07F861A680F5B00A75B9A = { 137 | LastSwiftMigration = 1120; 138 | }; 139 | }; 140 | }; 141 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "LeveldbExample" */; 142 | compatibilityVersion = "Xcode 12.0"; 143 | developmentRegion = en; 144 | hasScannedForEncodings = 0; 145 | knownRegions = ( 146 | en, 147 | Base, 148 | ); 149 | mainGroup = 83CBB9F61A601CBA00E9B192; 150 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 151 | projectDirPath = ""; 152 | projectRoot = ""; 153 | targets = ( 154 | 13B07F861A680F5B00A75B9A /* LeveldbExample */, 155 | ); 156 | }; 157 | /* End PBXProject section */ 158 | 159 | /* Begin PBXResourcesBuildPhase section */ 160 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 161 | isa = PBXResourcesBuildPhase; 162 | buildActionMask = 2147483647; 163 | files = ( 164 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, 165 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | "$(SRCROOT)/.xcode.env.local", 179 | "$(SRCROOT)/.xcode.env", 180 | ); 181 | name = "Bundle React Native code and images"; 182 | outputPaths = ( 183 | ); 184 | runOnlyForDeploymentPostprocessing = 0; 185 | shellPath = /bin/sh; 186 | shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; 187 | }; 188 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { 189 | isa = PBXShellScriptBuildPhase; 190 | buildActionMask = 2147483647; 191 | files = ( 192 | ); 193 | inputFileListPaths = ( 194 | "${PODS_ROOT}/Target Support Files/Pods-LeveldbExample/Pods-LeveldbExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", 195 | ); 196 | name = "[CP] Embed Pods Frameworks"; 197 | outputFileListPaths = ( 198 | "${PODS_ROOT}/Target Support Files/Pods-LeveldbExample/Pods-LeveldbExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | shellPath = /bin/sh; 202 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-LeveldbExample/Pods-LeveldbExample-frameworks.sh\"\n"; 203 | showEnvVarsInLog = 0; 204 | }; 205 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = { 206 | isa = PBXShellScriptBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | ); 210 | inputFileListPaths = ( 211 | ); 212 | inputPaths = ( 213 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 214 | "${PODS_ROOT}/Manifest.lock", 215 | ); 216 | name = "[CP] Check Pods Manifest.lock"; 217 | outputFileListPaths = ( 218 | ); 219 | outputPaths = ( 220 | "$(DERIVED_FILE_DIR)/Pods-LeveldbExample-checkManifestLockResult.txt", 221 | ); 222 | runOnlyForDeploymentPostprocessing = 0; 223 | shellPath = /bin/sh; 224 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 225 | showEnvVarsInLog = 0; 226 | }; 227 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = { 228 | isa = PBXShellScriptBuildPhase; 229 | buildActionMask = 2147483647; 230 | files = ( 231 | ); 232 | inputFileListPaths = ( 233 | "${PODS_ROOT}/Target Support Files/Pods-LeveldbExample/Pods-LeveldbExample-resources-${CONFIGURATION}-input-files.xcfilelist", 234 | ); 235 | name = "[CP] Copy Pods Resources"; 236 | outputFileListPaths = ( 237 | "${PODS_ROOT}/Target Support Files/Pods-LeveldbExample/Pods-LeveldbExample-resources-${CONFIGURATION}-output-files.xcfilelist", 238 | ); 239 | runOnlyForDeploymentPostprocessing = 0; 240 | shellPath = /bin/sh; 241 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-LeveldbExample/Pods-LeveldbExample-resources.sh\"\n"; 242 | showEnvVarsInLog = 0; 243 | }; 244 | FD10A7F022414F080027D42C /* Start Packager */ = { 245 | isa = PBXShellScriptBuildPhase; 246 | buildActionMask = 2147483647; 247 | files = ( 248 | ); 249 | inputFileListPaths = ( 250 | ); 251 | inputPaths = ( 252 | ); 253 | name = "Start Packager"; 254 | outputFileListPaths = ( 255 | ); 256 | outputPaths = ( 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | shellPath = /bin/sh; 260 | shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; 261 | showEnvVarsInLog = 0; 262 | }; 263 | /* End PBXShellScriptBuildPhase section */ 264 | 265 | /* Begin PBXSourcesBuildPhase section */ 266 | 13B07F871A680F5B00A75B9A /* Sources */ = { 267 | isa = PBXSourcesBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, 271 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | }; 275 | /* End PBXSourcesBuildPhase section */ 276 | 277 | /* Begin XCBuildConfiguration section */ 278 | 13B07F941A680F5B00A75B9A /* Debug */ = { 279 | isa = XCBuildConfiguration; 280 | baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-LeveldbExample.debug.xcconfig */; 281 | buildSettings = { 282 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 283 | CLANG_ENABLE_MODULES = YES; 284 | CURRENT_PROJECT_VERSION = 1; 285 | ENABLE_BITCODE = NO; 286 | INFOPLIST_FILE = LeveldbExample/Info.plist; 287 | LD_RUNPATH_SEARCH_PATHS = ( 288 | "$(inherited)", 289 | "@executable_path/Frameworks", 290 | ); 291 | MARKETING_VERSION = 1.0; 292 | OTHER_LDFLAGS = ( 293 | "$(inherited)", 294 | "-ObjC", 295 | "-lc++", 296 | ); 297 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.LeveldbExample.$(PRODUCT_NAME:rfc1034identifier)"; 298 | PRODUCT_NAME = LeveldbExample; 299 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 300 | SWIFT_VERSION = 5.0; 301 | VERSIONING_SYSTEM = "apple-generic"; 302 | }; 303 | name = Debug; 304 | }; 305 | 13B07F951A680F5B00A75B9A /* Release */ = { 306 | isa = XCBuildConfiguration; 307 | baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-LeveldbExample.release.xcconfig */; 308 | buildSettings = { 309 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 310 | CLANG_ENABLE_MODULES = YES; 311 | CURRENT_PROJECT_VERSION = 1; 312 | INFOPLIST_FILE = LeveldbExample/Info.plist; 313 | LD_RUNPATH_SEARCH_PATHS = ( 314 | "$(inherited)", 315 | "@executable_path/Frameworks", 316 | ); 317 | MARKETING_VERSION = 1.0; 318 | OTHER_LDFLAGS = ( 319 | "$(inherited)", 320 | "-ObjC", 321 | "-lc++", 322 | ); 323 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.LeveldbExample.$(PRODUCT_NAME:rfc1034identifier)"; 324 | PRODUCT_NAME = LeveldbExample; 325 | SWIFT_VERSION = 5.0; 326 | VERSIONING_SYSTEM = "apple-generic"; 327 | }; 328 | name = Release; 329 | }; 330 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 331 | isa = XCBuildConfiguration; 332 | buildSettings = { 333 | ALWAYS_SEARCH_USER_PATHS = NO; 334 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 335 | CLANG_CXX_LANGUAGE_STANDARD = "c++17"; 336 | CLANG_CXX_LIBRARY = "libc++"; 337 | CLANG_ENABLE_MODULES = YES; 338 | CLANG_ENABLE_OBJC_ARC = YES; 339 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 340 | CLANG_WARN_BOOL_CONVERSION = YES; 341 | CLANG_WARN_COMMA = YES; 342 | CLANG_WARN_CONSTANT_CONVERSION = YES; 343 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 344 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 345 | CLANG_WARN_EMPTY_BODY = YES; 346 | CLANG_WARN_ENUM_CONVERSION = YES; 347 | CLANG_WARN_INFINITE_RECURSION = YES; 348 | CLANG_WARN_INT_CONVERSION = YES; 349 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 350 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 351 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 352 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 353 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 354 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 355 | CLANG_WARN_STRICT_PROTOTYPES = YES; 356 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 357 | CLANG_WARN_UNREACHABLE_CODE = YES; 358 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 359 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 360 | COPY_PHASE_STRIP = NO; 361 | ENABLE_STRICT_OBJC_MSGSEND = YES; 362 | ENABLE_TESTABILITY = YES; 363 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; 364 | GCC_C_LANGUAGE_STANDARD = gnu99; 365 | GCC_DYNAMIC_NO_PIC = NO; 366 | GCC_NO_COMMON_BLOCKS = YES; 367 | GCC_OPTIMIZATION_LEVEL = 0; 368 | GCC_PREPROCESSOR_DEFINITIONS = ( 369 | "DEBUG=1", 370 | "$(inherited)", 371 | _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION, 372 | ); 373 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 374 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 375 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 376 | GCC_WARN_UNDECLARED_SELECTOR = YES; 377 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 378 | GCC_WARN_UNUSED_FUNCTION = YES; 379 | GCC_WARN_UNUSED_VARIABLE = YES; 380 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 381 | LD_RUNPATH_SEARCH_PATHS = ( 382 | /usr/lib/swift, 383 | "$(inherited)", 384 | ); 385 | LIBRARY_SEARCH_PATHS = ( 386 | "\"$(SDKROOT)/usr/lib/swift\"", 387 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 388 | "\"$(inherited)\"", 389 | ); 390 | MTL_ENABLE_DEBUG_INFO = YES; 391 | ONLY_ACTIVE_ARCH = YES; 392 | OTHER_CFLAGS = ( 393 | "$(inherited)", 394 | " ", 395 | ); 396 | OTHER_CPLUSPLUSFLAGS = ( 397 | "$(OTHER_CFLAGS)", 398 | "-DFOLLY_NO_CONFIG", 399 | "-DFOLLY_MOBILE=1", 400 | "-DFOLLY_USE_LIBCPP=1", 401 | " ", 402 | ); 403 | OTHER_LDFLAGS = ( 404 | "$(inherited)", 405 | "-Wl", 406 | "-ld_classic", 407 | ); 408 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; 409 | SDKROOT = iphoneos; 410 | }; 411 | name = Debug; 412 | }; 413 | 83CBBA211A601CBA00E9B192 /* Release */ = { 414 | isa = XCBuildConfiguration; 415 | buildSettings = { 416 | ALWAYS_SEARCH_USER_PATHS = NO; 417 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 418 | CLANG_CXX_LANGUAGE_STANDARD = "c++17"; 419 | CLANG_CXX_LIBRARY = "libc++"; 420 | CLANG_ENABLE_MODULES = YES; 421 | CLANG_ENABLE_OBJC_ARC = YES; 422 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 423 | CLANG_WARN_BOOL_CONVERSION = YES; 424 | CLANG_WARN_COMMA = YES; 425 | CLANG_WARN_CONSTANT_CONVERSION = YES; 426 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 427 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 428 | CLANG_WARN_EMPTY_BODY = YES; 429 | CLANG_WARN_ENUM_CONVERSION = YES; 430 | CLANG_WARN_INFINITE_RECURSION = YES; 431 | CLANG_WARN_INT_CONVERSION = YES; 432 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 433 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 434 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 435 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 436 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 437 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 438 | CLANG_WARN_STRICT_PROTOTYPES = YES; 439 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 440 | CLANG_WARN_UNREACHABLE_CODE = YES; 441 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 442 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 443 | COPY_PHASE_STRIP = YES; 444 | ENABLE_NS_ASSERTIONS = NO; 445 | ENABLE_STRICT_OBJC_MSGSEND = YES; 446 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; 447 | GCC_C_LANGUAGE_STANDARD = gnu99; 448 | GCC_NO_COMMON_BLOCKS = YES; 449 | GCC_PREPROCESSOR_DEFINITIONS = ( 450 | "$(inherited)", 451 | _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION, 452 | ); 453 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 454 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 455 | GCC_WARN_UNDECLARED_SELECTOR = YES; 456 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 457 | GCC_WARN_UNUSED_FUNCTION = YES; 458 | GCC_WARN_UNUSED_VARIABLE = YES; 459 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 460 | LD_RUNPATH_SEARCH_PATHS = ( 461 | /usr/lib/swift, 462 | "$(inherited)", 463 | ); 464 | LIBRARY_SEARCH_PATHS = ( 465 | "\"$(SDKROOT)/usr/lib/swift\"", 466 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 467 | "\"$(inherited)\"", 468 | ); 469 | MTL_ENABLE_DEBUG_INFO = NO; 470 | OTHER_CFLAGS = ( 471 | "$(inherited)", 472 | " ", 473 | ); 474 | OTHER_CPLUSPLUSFLAGS = ( 475 | "$(OTHER_CFLAGS)", 476 | "-DFOLLY_NO_CONFIG", 477 | "-DFOLLY_MOBILE=1", 478 | "-DFOLLY_USE_LIBCPP=1", 479 | " ", 480 | ); 481 | OTHER_LDFLAGS = ( 482 | "$(inherited)", 483 | "-Wl", 484 | "-ld_classic", 485 | ); 486 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; 487 | SDKROOT = iphoneos; 488 | VALIDATE_PRODUCT = YES; 489 | }; 490 | name = Release; 491 | }; 492 | /* End XCBuildConfiguration section */ 493 | 494 | /* Begin XCConfigurationList section */ 495 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "LeveldbExample" */ = { 496 | isa = XCConfigurationList; 497 | buildConfigurations = ( 498 | 13B07F941A680F5B00A75B9A /* Debug */, 499 | 13B07F951A680F5B00A75B9A /* Release */, 500 | ); 501 | defaultConfigurationIsVisible = 0; 502 | defaultConfigurationName = Release; 503 | }; 504 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "LeveldbExample" */ = { 505 | isa = XCConfigurationList; 506 | buildConfigurations = ( 507 | 83CBBA201A601CBA00E9B192 /* Debug */, 508 | 83CBBA211A601CBA00E9B192 /* Release */, 509 | ); 510 | defaultConfigurationIsVisible = 0; 511 | defaultConfigurationName = Release; 512 | }; 513 | /* End XCConfigurationList section */ 514 | }; 515 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 516 | } 517 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample.xcodeproj/xcshareddata/xcschemes/LeveldbExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 42 | 44 | 50 | 51 | 52 | 53 | 59 | 61 | 67 | 68 | 69 | 70 | 72 | 73 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.moduleName = @"main"; 10 | // You can add your custom initial props in the dictionary below. 11 | // They will be passed down to the ViewController used by React Native. 12 | self.initialProps = @{}; 13 | 14 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | } 16 | 17 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 18 | { 19 | #if DEBUG 20 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 21 | #else 22 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 23 | #endif 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | localhost 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | NSLocationWhenInUseUsageDescription 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /example/ios/LeveldbExample/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | require Pod::Executable.execute_command('node', ['-p', 3 | 'require.resolve( 4 | "react-native/scripts/react_native_pods.rb", 5 | {paths: [process.argv[1]]}, 6 | )', __dir__]).strip 7 | 8 | platform :ios, min_ios_version_supported 9 | prepare_react_native_project! 10 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. 11 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded 12 | # 13 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` 14 | # ```js 15 | # module.exports = { 16 | # dependencies: { 17 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), 18 | # ``` 19 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled 20 | linkage = ENV['USE_FRAMEWORKS'] 21 | if linkage != nil 22 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 23 | use_frameworks! :linkage => linkage.to_sym 24 | end 25 | 26 | target 'LeveldbExample' do 27 | config = use_native_modules! 28 | 29 | # Flags change depending on the env values. 30 | flags = get_default_flags() 31 | 32 | use_react_native!( 33 | :path => config[:reactNativePath], 34 | # Hermes is now enabled by default. Disable by setting this flag to false. 35 | :hermes_enabled => true, 36 | :fabric_enabled => flags[:fabric_enabled], 37 | # Enables Flipper. 38 | # 39 | # Note that if you have use_frameworks! enabled, Flipper will not work and 40 | # you should disable the next line. 41 | :flipper_configuration => flipper_config, 42 | # An absolute path to your application root. 43 | :app_path => "#{Pod::Config.instance.installation_root}/.." 44 | ) 45 | 46 | post_install do |installer| 47 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 48 | react_native_post_install( 49 | installer, 50 | config[:reactNativePath], 51 | :mac_catalyst_enabled => false 52 | ) 53 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - boost (1.76.0) 3 | - CocoaAsyncSocket (7.6.5) 4 | - DoubleConversion (1.1.6) 5 | - FBLazyVector (0.72.7) 6 | - FBReactNativeSpec (0.72.7): 7 | - RCT-Folly (= 2021.07.22.00) 8 | - RCTRequired (= 0.72.7) 9 | - RCTTypeSafety (= 0.72.7) 10 | - React-Core (= 0.72.7) 11 | - React-jsi (= 0.72.7) 12 | - ReactCommon/turbomodule/core (= 0.72.7) 13 | - Flipper (0.182.0): 14 | - Flipper-Folly (~> 2.6) 15 | - Flipper-Boost-iOSX (1.76.0.1.11) 16 | - Flipper-DoubleConversion (3.2.0.1) 17 | - Flipper-Fmt (7.1.7) 18 | - Flipper-Folly (2.6.10): 19 | - Flipper-Boost-iOSX 20 | - Flipper-DoubleConversion 21 | - Flipper-Fmt (= 7.1.7) 22 | - Flipper-Glog 23 | - libevent (~> 2.1.12) 24 | - OpenSSL-Universal (= 1.1.1100) 25 | - Flipper-Glog (0.5.0.5) 26 | - Flipper-PeerTalk (0.0.4) 27 | - FlipperKit (0.182.0): 28 | - FlipperKit/Core (= 0.182.0) 29 | - FlipperKit/Core (0.182.0): 30 | - Flipper (~> 0.182.0) 31 | - FlipperKit/CppBridge 32 | - FlipperKit/FBCxxFollyDynamicConvert 33 | - FlipperKit/FBDefines 34 | - FlipperKit/FKPortForwarding 35 | - SocketRocket (~> 0.6.0) 36 | - FlipperKit/CppBridge (0.182.0): 37 | - Flipper (~> 0.182.0) 38 | - FlipperKit/FBCxxFollyDynamicConvert (0.182.0): 39 | - Flipper-Folly (~> 2.6) 40 | - FlipperKit/FBDefines (0.182.0) 41 | - FlipperKit/FKPortForwarding (0.182.0): 42 | - CocoaAsyncSocket (~> 7.6) 43 | - Flipper-PeerTalk (~> 0.0.4) 44 | - FlipperKit/FlipperKitHighlightOverlay (0.182.0) 45 | - FlipperKit/FlipperKitLayoutHelpers (0.182.0): 46 | - FlipperKit/Core 47 | - FlipperKit/FlipperKitHighlightOverlay 48 | - FlipperKit/FlipperKitLayoutTextSearchable 49 | - FlipperKit/FlipperKitLayoutIOSDescriptors (0.182.0): 50 | - FlipperKit/Core 51 | - FlipperKit/FlipperKitHighlightOverlay 52 | - FlipperKit/FlipperKitLayoutHelpers 53 | - YogaKit (~> 1.18) 54 | - FlipperKit/FlipperKitLayoutPlugin (0.182.0): 55 | - FlipperKit/Core 56 | - FlipperKit/FlipperKitHighlightOverlay 57 | - FlipperKit/FlipperKitLayoutHelpers 58 | - FlipperKit/FlipperKitLayoutIOSDescriptors 59 | - FlipperKit/FlipperKitLayoutTextSearchable 60 | - YogaKit (~> 1.18) 61 | - FlipperKit/FlipperKitLayoutTextSearchable (0.182.0) 62 | - FlipperKit/FlipperKitNetworkPlugin (0.182.0): 63 | - FlipperKit/Core 64 | - FlipperKit/FlipperKitReactPlugin (0.182.0): 65 | - FlipperKit/Core 66 | - FlipperKit/FlipperKitUserDefaultsPlugin (0.182.0): 67 | - FlipperKit/Core 68 | - FlipperKit/SKIOSNetworkPlugin (0.182.0): 69 | - FlipperKit/Core 70 | - FlipperKit/FlipperKitNetworkPlugin 71 | - fmt (6.2.1) 72 | - glog (0.3.5) 73 | - hermes-engine (0.72.7): 74 | - hermes-engine/Pre-built (= 0.72.7) 75 | - hermes-engine/Pre-built (0.72.7) 76 | - libevent (2.1.12) 77 | - OpenSSL-Universal (1.1.1100) 78 | - RCT-Folly (2021.07.22.00): 79 | - boost 80 | - DoubleConversion 81 | - fmt (~> 6.2.1) 82 | - glog 83 | - RCT-Folly/Default (= 2021.07.22.00) 84 | - RCT-Folly/Default (2021.07.22.00): 85 | - boost 86 | - DoubleConversion 87 | - fmt (~> 6.2.1) 88 | - glog 89 | - RCT-Folly/Futures (2021.07.22.00): 90 | - boost 91 | - DoubleConversion 92 | - fmt (~> 6.2.1) 93 | - glog 94 | - libevent 95 | - RCTRequired (0.72.7) 96 | - RCTTypeSafety (0.72.7): 97 | - FBLazyVector (= 0.72.7) 98 | - RCTRequired (= 0.72.7) 99 | - React-Core (= 0.72.7) 100 | - React (0.72.7): 101 | - React-Core (= 0.72.7) 102 | - React-Core/DevSupport (= 0.72.7) 103 | - React-Core/RCTWebSocket (= 0.72.7) 104 | - React-RCTActionSheet (= 0.72.7) 105 | - React-RCTAnimation (= 0.72.7) 106 | - React-RCTBlob (= 0.72.7) 107 | - React-RCTImage (= 0.72.7) 108 | - React-RCTLinking (= 0.72.7) 109 | - React-RCTNetwork (= 0.72.7) 110 | - React-RCTSettings (= 0.72.7) 111 | - React-RCTText (= 0.72.7) 112 | - React-RCTVibration (= 0.72.7) 113 | - React-callinvoker (0.72.7) 114 | - React-Codegen (0.72.7): 115 | - DoubleConversion 116 | - FBReactNativeSpec 117 | - glog 118 | - hermes-engine 119 | - RCT-Folly 120 | - RCTRequired 121 | - RCTTypeSafety 122 | - React-Core 123 | - React-jsi 124 | - React-jsiexecutor 125 | - React-NativeModulesApple 126 | - React-rncore 127 | - ReactCommon/turbomodule/bridging 128 | - ReactCommon/turbomodule/core 129 | - React-Core (0.72.7): 130 | - glog 131 | - hermes-engine 132 | - RCT-Folly (= 2021.07.22.00) 133 | - React-Core/Default (= 0.72.7) 134 | - React-cxxreact 135 | - React-hermes 136 | - React-jsi 137 | - React-jsiexecutor 138 | - React-perflogger 139 | - React-runtimeexecutor 140 | - React-utils 141 | - SocketRocket (= 0.6.1) 142 | - Yoga 143 | - React-Core/CoreModulesHeaders (0.72.7): 144 | - glog 145 | - hermes-engine 146 | - RCT-Folly (= 2021.07.22.00) 147 | - React-Core/Default 148 | - React-cxxreact 149 | - React-hermes 150 | - React-jsi 151 | - React-jsiexecutor 152 | - React-perflogger 153 | - React-runtimeexecutor 154 | - React-utils 155 | - SocketRocket (= 0.6.1) 156 | - Yoga 157 | - React-Core/Default (0.72.7): 158 | - glog 159 | - hermes-engine 160 | - RCT-Folly (= 2021.07.22.00) 161 | - React-cxxreact 162 | - React-hermes 163 | - React-jsi 164 | - React-jsiexecutor 165 | - React-perflogger 166 | - React-runtimeexecutor 167 | - React-utils 168 | - SocketRocket (= 0.6.1) 169 | - Yoga 170 | - React-Core/DevSupport (0.72.7): 171 | - glog 172 | - hermes-engine 173 | - RCT-Folly (= 2021.07.22.00) 174 | - React-Core/Default (= 0.72.7) 175 | - React-Core/RCTWebSocket (= 0.72.7) 176 | - React-cxxreact 177 | - React-hermes 178 | - React-jsi 179 | - React-jsiexecutor 180 | - React-jsinspector (= 0.72.7) 181 | - React-perflogger 182 | - React-runtimeexecutor 183 | - React-utils 184 | - SocketRocket (= 0.6.1) 185 | - Yoga 186 | - React-Core/RCTActionSheetHeaders (0.72.7): 187 | - glog 188 | - hermes-engine 189 | - RCT-Folly (= 2021.07.22.00) 190 | - React-Core/Default 191 | - React-cxxreact 192 | - React-hermes 193 | - React-jsi 194 | - React-jsiexecutor 195 | - React-perflogger 196 | - React-runtimeexecutor 197 | - React-utils 198 | - SocketRocket (= 0.6.1) 199 | - Yoga 200 | - React-Core/RCTAnimationHeaders (0.72.7): 201 | - glog 202 | - hermes-engine 203 | - RCT-Folly (= 2021.07.22.00) 204 | - React-Core/Default 205 | - React-cxxreact 206 | - React-hermes 207 | - React-jsi 208 | - React-jsiexecutor 209 | - React-perflogger 210 | - React-runtimeexecutor 211 | - React-utils 212 | - SocketRocket (= 0.6.1) 213 | - Yoga 214 | - React-Core/RCTBlobHeaders (0.72.7): 215 | - glog 216 | - hermes-engine 217 | - RCT-Folly (= 2021.07.22.00) 218 | - React-Core/Default 219 | - React-cxxreact 220 | - React-hermes 221 | - React-jsi 222 | - React-jsiexecutor 223 | - React-perflogger 224 | - React-runtimeexecutor 225 | - React-utils 226 | - SocketRocket (= 0.6.1) 227 | - Yoga 228 | - React-Core/RCTImageHeaders (0.72.7): 229 | - glog 230 | - hermes-engine 231 | - RCT-Folly (= 2021.07.22.00) 232 | - React-Core/Default 233 | - React-cxxreact 234 | - React-hermes 235 | - React-jsi 236 | - React-jsiexecutor 237 | - React-perflogger 238 | - React-runtimeexecutor 239 | - React-utils 240 | - SocketRocket (= 0.6.1) 241 | - Yoga 242 | - React-Core/RCTLinkingHeaders (0.72.7): 243 | - glog 244 | - hermes-engine 245 | - RCT-Folly (= 2021.07.22.00) 246 | - React-Core/Default 247 | - React-cxxreact 248 | - React-hermes 249 | - React-jsi 250 | - React-jsiexecutor 251 | - React-perflogger 252 | - React-runtimeexecutor 253 | - React-utils 254 | - SocketRocket (= 0.6.1) 255 | - Yoga 256 | - React-Core/RCTNetworkHeaders (0.72.7): 257 | - glog 258 | - hermes-engine 259 | - RCT-Folly (= 2021.07.22.00) 260 | - React-Core/Default 261 | - React-cxxreact 262 | - React-hermes 263 | - React-jsi 264 | - React-jsiexecutor 265 | - React-perflogger 266 | - React-runtimeexecutor 267 | - React-utils 268 | - SocketRocket (= 0.6.1) 269 | - Yoga 270 | - React-Core/RCTSettingsHeaders (0.72.7): 271 | - glog 272 | - hermes-engine 273 | - RCT-Folly (= 2021.07.22.00) 274 | - React-Core/Default 275 | - React-cxxreact 276 | - React-hermes 277 | - React-jsi 278 | - React-jsiexecutor 279 | - React-perflogger 280 | - React-runtimeexecutor 281 | - React-utils 282 | - SocketRocket (= 0.6.1) 283 | - Yoga 284 | - React-Core/RCTTextHeaders (0.72.7): 285 | - glog 286 | - hermes-engine 287 | - RCT-Folly (= 2021.07.22.00) 288 | - React-Core/Default 289 | - React-cxxreact 290 | - React-hermes 291 | - React-jsi 292 | - React-jsiexecutor 293 | - React-perflogger 294 | - React-runtimeexecutor 295 | - React-utils 296 | - SocketRocket (= 0.6.1) 297 | - Yoga 298 | - React-Core/RCTVibrationHeaders (0.72.7): 299 | - glog 300 | - hermes-engine 301 | - RCT-Folly (= 2021.07.22.00) 302 | - React-Core/Default 303 | - React-cxxreact 304 | - React-hermes 305 | - React-jsi 306 | - React-jsiexecutor 307 | - React-perflogger 308 | - React-runtimeexecutor 309 | - React-utils 310 | - SocketRocket (= 0.6.1) 311 | - Yoga 312 | - React-Core/RCTWebSocket (0.72.7): 313 | - glog 314 | - hermes-engine 315 | - RCT-Folly (= 2021.07.22.00) 316 | - React-Core/Default (= 0.72.7) 317 | - React-cxxreact 318 | - React-hermes 319 | - React-jsi 320 | - React-jsiexecutor 321 | - React-perflogger 322 | - React-runtimeexecutor 323 | - React-utils 324 | - SocketRocket (= 0.6.1) 325 | - Yoga 326 | - React-CoreModules (0.72.7): 327 | - RCT-Folly (= 2021.07.22.00) 328 | - RCTTypeSafety (= 0.72.7) 329 | - React-Codegen (= 0.72.7) 330 | - React-Core/CoreModulesHeaders (= 0.72.7) 331 | - React-jsi (= 0.72.7) 332 | - React-RCTBlob 333 | - React-RCTImage (= 0.72.7) 334 | - ReactCommon/turbomodule/core (= 0.72.7) 335 | - SocketRocket (= 0.6.1) 336 | - React-cxxreact (0.72.7): 337 | - boost (= 1.76.0) 338 | - DoubleConversion 339 | - glog 340 | - hermes-engine 341 | - RCT-Folly (= 2021.07.22.00) 342 | - React-callinvoker (= 0.72.7) 343 | - React-debug (= 0.72.7) 344 | - React-jsi (= 0.72.7) 345 | - React-jsinspector (= 0.72.7) 346 | - React-logger (= 0.72.7) 347 | - React-perflogger (= 0.72.7) 348 | - React-runtimeexecutor (= 0.72.7) 349 | - React-debug (0.72.7) 350 | - React-hermes (0.72.7): 351 | - DoubleConversion 352 | - glog 353 | - hermes-engine 354 | - RCT-Folly (= 2021.07.22.00) 355 | - RCT-Folly/Futures (= 2021.07.22.00) 356 | - React-cxxreact (= 0.72.7) 357 | - React-jsi 358 | - React-jsiexecutor (= 0.72.7) 359 | - React-jsinspector (= 0.72.7) 360 | - React-perflogger (= 0.72.7) 361 | - React-jsi (0.72.7): 362 | - boost (= 1.76.0) 363 | - DoubleConversion 364 | - glog 365 | - hermes-engine 366 | - RCT-Folly (= 2021.07.22.00) 367 | - React-jsiexecutor (0.72.7): 368 | - DoubleConversion 369 | - glog 370 | - hermes-engine 371 | - RCT-Folly (= 2021.07.22.00) 372 | - React-cxxreact (= 0.72.7) 373 | - React-jsi (= 0.72.7) 374 | - React-perflogger (= 0.72.7) 375 | - React-jsinspector (0.72.7) 376 | - React-logger (0.72.7): 377 | - glog 378 | - react-native-leveldb (3.3.3): 379 | - React-Core 380 | - React-NativeModulesApple (0.72.7): 381 | - hermes-engine 382 | - React-callinvoker 383 | - React-Core 384 | - React-cxxreact 385 | - React-jsi 386 | - React-runtimeexecutor 387 | - ReactCommon/turbomodule/bridging 388 | - ReactCommon/turbomodule/core 389 | - React-perflogger (0.72.7) 390 | - React-RCTActionSheet (0.72.7): 391 | - React-Core/RCTActionSheetHeaders (= 0.72.7) 392 | - React-RCTAnimation (0.72.7): 393 | - RCT-Folly (= 2021.07.22.00) 394 | - RCTTypeSafety (= 0.72.7) 395 | - React-Codegen (= 0.72.7) 396 | - React-Core/RCTAnimationHeaders (= 0.72.7) 397 | - React-jsi (= 0.72.7) 398 | - ReactCommon/turbomodule/core (= 0.72.7) 399 | - React-RCTAppDelegate (0.72.7): 400 | - RCT-Folly 401 | - RCTRequired 402 | - RCTTypeSafety 403 | - React-Core 404 | - React-CoreModules 405 | - React-hermes 406 | - React-NativeModulesApple 407 | - React-RCTImage 408 | - React-RCTNetwork 409 | - React-runtimescheduler 410 | - ReactCommon/turbomodule/core 411 | - React-RCTBlob (0.72.7): 412 | - hermes-engine 413 | - RCT-Folly (= 2021.07.22.00) 414 | - React-Codegen (= 0.72.7) 415 | - React-Core/RCTBlobHeaders (= 0.72.7) 416 | - React-Core/RCTWebSocket (= 0.72.7) 417 | - React-jsi (= 0.72.7) 418 | - React-RCTNetwork (= 0.72.7) 419 | - ReactCommon/turbomodule/core (= 0.72.7) 420 | - React-RCTImage (0.72.7): 421 | - RCT-Folly (= 2021.07.22.00) 422 | - RCTTypeSafety (= 0.72.7) 423 | - React-Codegen (= 0.72.7) 424 | - React-Core/RCTImageHeaders (= 0.72.7) 425 | - React-jsi (= 0.72.7) 426 | - React-RCTNetwork (= 0.72.7) 427 | - ReactCommon/turbomodule/core (= 0.72.7) 428 | - React-RCTLinking (0.72.7): 429 | - React-Codegen (= 0.72.7) 430 | - React-Core/RCTLinkingHeaders (= 0.72.7) 431 | - React-jsi (= 0.72.7) 432 | - ReactCommon/turbomodule/core (= 0.72.7) 433 | - React-RCTNetwork (0.72.7): 434 | - RCT-Folly (= 2021.07.22.00) 435 | - RCTTypeSafety (= 0.72.7) 436 | - React-Codegen (= 0.72.7) 437 | - React-Core/RCTNetworkHeaders (= 0.72.7) 438 | - React-jsi (= 0.72.7) 439 | - ReactCommon/turbomodule/core (= 0.72.7) 440 | - React-RCTSettings (0.72.7): 441 | - RCT-Folly (= 2021.07.22.00) 442 | - RCTTypeSafety (= 0.72.7) 443 | - React-Codegen (= 0.72.7) 444 | - React-Core/RCTSettingsHeaders (= 0.72.7) 445 | - React-jsi (= 0.72.7) 446 | - ReactCommon/turbomodule/core (= 0.72.7) 447 | - React-RCTText (0.72.7): 448 | - React-Core/RCTTextHeaders (= 0.72.7) 449 | - React-RCTVibration (0.72.7): 450 | - RCT-Folly (= 2021.07.22.00) 451 | - React-Codegen (= 0.72.7) 452 | - React-Core/RCTVibrationHeaders (= 0.72.7) 453 | - React-jsi (= 0.72.7) 454 | - ReactCommon/turbomodule/core (= 0.72.7) 455 | - React-rncore (0.72.7) 456 | - React-runtimeexecutor (0.72.7): 457 | - React-jsi (= 0.72.7) 458 | - React-runtimescheduler (0.72.7): 459 | - glog 460 | - hermes-engine 461 | - RCT-Folly (= 2021.07.22.00) 462 | - React-callinvoker 463 | - React-debug 464 | - React-jsi 465 | - React-runtimeexecutor 466 | - React-utils (0.72.7): 467 | - glog 468 | - RCT-Folly (= 2021.07.22.00) 469 | - React-debug 470 | - ReactCommon/turbomodule/bridging (0.72.7): 471 | - DoubleConversion 472 | - glog 473 | - hermes-engine 474 | - RCT-Folly (= 2021.07.22.00) 475 | - React-callinvoker (= 0.72.7) 476 | - React-cxxreact (= 0.72.7) 477 | - React-jsi (= 0.72.7) 478 | - React-logger (= 0.72.7) 479 | - React-perflogger (= 0.72.7) 480 | - ReactCommon/turbomodule/core (0.72.7): 481 | - DoubleConversion 482 | - glog 483 | - hermes-engine 484 | - RCT-Folly (= 2021.07.22.00) 485 | - React-callinvoker (= 0.72.7) 486 | - React-cxxreact (= 0.72.7) 487 | - React-jsi (= 0.72.7) 488 | - React-logger (= 0.72.7) 489 | - React-perflogger (= 0.72.7) 490 | - RNCAsyncStorage (1.19.5): 491 | - React-Core 492 | - SocketRocket (0.6.1) 493 | - Yoga (1.14.0) 494 | - YogaKit (1.18.1): 495 | - Yoga (~> 1.14) 496 | 497 | DEPENDENCIES: 498 | - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) 499 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) 500 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) 501 | - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) 502 | - Flipper (= 0.182.0) 503 | - Flipper-Boost-iOSX (= 1.76.0.1.11) 504 | - Flipper-DoubleConversion (= 3.2.0.1) 505 | - Flipper-Fmt (= 7.1.7) 506 | - Flipper-Folly (= 2.6.10) 507 | - Flipper-Glog (= 0.5.0.5) 508 | - Flipper-PeerTalk (= 0.0.4) 509 | - FlipperKit (= 0.182.0) 510 | - FlipperKit/Core (= 0.182.0) 511 | - FlipperKit/CppBridge (= 0.182.0) 512 | - FlipperKit/FBCxxFollyDynamicConvert (= 0.182.0) 513 | - FlipperKit/FBDefines (= 0.182.0) 514 | - FlipperKit/FKPortForwarding (= 0.182.0) 515 | - FlipperKit/FlipperKitHighlightOverlay (= 0.182.0) 516 | - FlipperKit/FlipperKitLayoutPlugin (= 0.182.0) 517 | - FlipperKit/FlipperKitLayoutTextSearchable (= 0.182.0) 518 | - FlipperKit/FlipperKitNetworkPlugin (= 0.182.0) 519 | - FlipperKit/FlipperKitReactPlugin (= 0.182.0) 520 | - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.182.0) 521 | - FlipperKit/SKIOSNetworkPlugin (= 0.182.0) 522 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) 523 | - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) 524 | - libevent (~> 2.1.12) 525 | - OpenSSL-Universal (= 1.1.1100) 526 | - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) 527 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) 528 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) 529 | - React (from `../node_modules/react-native/`) 530 | - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`) 531 | - React-Codegen (from `build/generated/ios`) 532 | - React-Core (from `../node_modules/react-native/`) 533 | - React-Core/DevSupport (from `../node_modules/react-native/`) 534 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`) 535 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) 536 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) 537 | - React-debug (from `../node_modules/react-native/ReactCommon/react/debug`) 538 | - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) 539 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) 540 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) 541 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) 542 | - React-logger (from `../node_modules/react-native/ReactCommon/logger`) 543 | - react-native-leveldb (from `../..`) 544 | - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) 545 | - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) 546 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) 547 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) 548 | - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`) 549 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) 550 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) 551 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) 552 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) 553 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) 554 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`) 555 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) 556 | - React-rncore (from `../node_modules/react-native/ReactCommon`) 557 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) 558 | - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) 559 | - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) 560 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) 561 | - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" 562 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) 563 | 564 | SPEC REPOS: 565 | trunk: 566 | - CocoaAsyncSocket 567 | - Flipper 568 | - Flipper-Boost-iOSX 569 | - Flipper-DoubleConversion 570 | - Flipper-Fmt 571 | - Flipper-Folly 572 | - Flipper-Glog 573 | - Flipper-PeerTalk 574 | - FlipperKit 575 | - fmt 576 | - libevent 577 | - OpenSSL-Universal 578 | - SocketRocket 579 | - YogaKit 580 | 581 | EXTERNAL SOURCES: 582 | boost: 583 | :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec" 584 | DoubleConversion: 585 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" 586 | FBLazyVector: 587 | :path: "../node_modules/react-native/Libraries/FBLazyVector" 588 | FBReactNativeSpec: 589 | :path: "../node_modules/react-native/React/FBReactNativeSpec" 590 | glog: 591 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" 592 | hermes-engine: 593 | :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" 594 | :tag: hermes-2023-08-07-RNv0.72.4-813b2def12bc9df02654b3e3653ae4a68d0572e0 595 | RCT-Folly: 596 | :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" 597 | RCTRequired: 598 | :path: "../node_modules/react-native/Libraries/RCTRequired" 599 | RCTTypeSafety: 600 | :path: "../node_modules/react-native/Libraries/TypeSafety" 601 | React: 602 | :path: "../node_modules/react-native/" 603 | React-callinvoker: 604 | :path: "../node_modules/react-native/ReactCommon/callinvoker" 605 | React-Codegen: 606 | :path: build/generated/ios 607 | React-Core: 608 | :path: "../node_modules/react-native/" 609 | React-CoreModules: 610 | :path: "../node_modules/react-native/React/CoreModules" 611 | React-cxxreact: 612 | :path: "../node_modules/react-native/ReactCommon/cxxreact" 613 | React-debug: 614 | :path: "../node_modules/react-native/ReactCommon/react/debug" 615 | React-hermes: 616 | :path: "../node_modules/react-native/ReactCommon/hermes" 617 | React-jsi: 618 | :path: "../node_modules/react-native/ReactCommon/jsi" 619 | React-jsiexecutor: 620 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor" 621 | React-jsinspector: 622 | :path: "../node_modules/react-native/ReactCommon/jsinspector" 623 | React-logger: 624 | :path: "../node_modules/react-native/ReactCommon/logger" 625 | react-native-leveldb: 626 | :path: "../.." 627 | React-NativeModulesApple: 628 | :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" 629 | React-perflogger: 630 | :path: "../node_modules/react-native/ReactCommon/reactperflogger" 631 | React-RCTActionSheet: 632 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS" 633 | React-RCTAnimation: 634 | :path: "../node_modules/react-native/Libraries/NativeAnimation" 635 | React-RCTAppDelegate: 636 | :path: "../node_modules/react-native/Libraries/AppDelegate" 637 | React-RCTBlob: 638 | :path: "../node_modules/react-native/Libraries/Blob" 639 | React-RCTImage: 640 | :path: "../node_modules/react-native/Libraries/Image" 641 | React-RCTLinking: 642 | :path: "../node_modules/react-native/Libraries/LinkingIOS" 643 | React-RCTNetwork: 644 | :path: "../node_modules/react-native/Libraries/Network" 645 | React-RCTSettings: 646 | :path: "../node_modules/react-native/Libraries/Settings" 647 | React-RCTText: 648 | :path: "../node_modules/react-native/Libraries/Text" 649 | React-RCTVibration: 650 | :path: "../node_modules/react-native/Libraries/Vibration" 651 | React-rncore: 652 | :path: "../node_modules/react-native/ReactCommon" 653 | React-runtimeexecutor: 654 | :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" 655 | React-runtimescheduler: 656 | :path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler" 657 | React-utils: 658 | :path: "../node_modules/react-native/ReactCommon/react/utils" 659 | ReactCommon: 660 | :path: "../node_modules/react-native/ReactCommon" 661 | RNCAsyncStorage: 662 | :path: "../node_modules/@react-native-async-storage/async-storage" 663 | Yoga: 664 | :path: "../node_modules/react-native/ReactCommon/yoga" 665 | 666 | SPEC CHECKSUMS: 667 | boost: 57d2868c099736d80fcd648bf211b4431e51a558 668 | CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 669 | DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 670 | FBLazyVector: 5fbbff1d7734827299274638deb8ba3024f6c597 671 | FBReactNativeSpec: 638095fe8a01506634d77b260ef8a322019ac671 672 | Flipper: 6edb735e6c3e332975d1b17956bcc584eccf5818 673 | Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c 674 | Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 675 | Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b 676 | Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3 677 | Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446 678 | Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 679 | FlipperKit: 2efad7007d6745a3f95e4034d547be637f89d3f6 680 | fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 681 | glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b 682 | hermes-engine: 9180d43df05c1ed658a87cc733dc3044cf90c00a 683 | libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 684 | OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c 685 | RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 686 | RCTRequired: 83bca1c184feb4d2e51c72c8369b83d641443f95 687 | RCTTypeSafety: 13c4a87a16d7db6cd66006ce9759f073402ef85b 688 | React: e67aa9f99957c7611c392b5e49355d877d6525e2 689 | React-callinvoker: 2790c09d964c2e5404b5410cde91b152e3746b7b 690 | React-Codegen: e6e05e105ca7cdb990f4d609985a2a689d8d0653 691 | React-Core: 9283f1e7d0d5e3d33ad298547547b1b43912534c 692 | React-CoreModules: 6312c9b2fec4329d9ae6a2b8c350032d1664c51b 693 | React-cxxreact: 7da72565656c8ac7f97c9a031d0b199bbdec0640 694 | React-debug: 4accb2b9dc09b575206d2c42f4082990a52ae436 695 | React-hermes: 1299a94f255f59a72d5baa54a2ca2e1eee104947 696 | React-jsi: 2208de64c3a41714ac04e86975386fc49116ea13 697 | React-jsiexecutor: c49502e5d02112247ee4526bc3ccfc891ae3eb9b 698 | React-jsinspector: 8baadae51f01d867c3921213a25ab78ab4fbcd91 699 | React-logger: 8edc785c47c8686c7962199a307015e2ce9a0e4f 700 | react-native-leveldb: 25e637abdbe719dfae580ab336b7d18506532d1f 701 | React-NativeModulesApple: b6868ee904013a7923128892ee4a032498a1024a 702 | React-perflogger: 31ea61077185eb1428baf60c0db6e2886f141a5a 703 | React-RCTActionSheet: 392090a3abc8992eb269ef0eaa561750588fc39d 704 | React-RCTAnimation: 4b3cc6a29474bc0d78c4f04b52ab59bf760e8a9b 705 | React-RCTAppDelegate: 89b015b29885109addcabecdf3b2e833905437c7 706 | React-RCTBlob: 3e23dcbe6638897b5605e46d0d62955d78e8d27b 707 | React-RCTImage: 8a5d339d614a90a183fc1b8b6a7eb44e2e703943 708 | React-RCTLinking: b37dfbf646d77c326f9eae094b1fcd575b1c24c7 709 | React-RCTNetwork: 8bed9b2461c7d8a7d14e63df9b16181c448beebc 710 | React-RCTSettings: 506a5f09a455123a8873801b70aa7b4010b76b01 711 | React-RCTText: 3c71ecaad8ee010b79632ea2590f86c02f5cce17 712 | React-RCTVibration: d1b78ca38f61ea4b3e9ebb2ddbd0b5662631d99b 713 | React-rncore: bfc2f6568b6fecbae6f2f774e95c60c3c9e95bf2 714 | React-runtimeexecutor: 47b0a2d5bbb416db65ef881a6f7bdcfefa0001ab 715 | React-runtimescheduler: 7649c3b46c8dee1853691ecf60146a16ae59253c 716 | React-utils: 56838edeaaf651220d1e53cd0b8934fb8ce68415 717 | ReactCommon: 5f704096ccf7733b390f59043b6fa9cc180ee4f6 718 | RNCAsyncStorage: f2974eca860c16a3e56eea5771fda8d12e2d2057 719 | SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 720 | Yoga: 4c3aa327e4a6a23eeacd71f61c81df1bcdf677d5 721 | YogaKit: f782866e155069a2cca2517aafea43200b01fd5a 722 | 723 | PODFILE CHECKSUM: ce0af5f784fef92badc988704aa45a4ec7fa8dff 724 | 725 | COCOAPODS: 1.16.2 726 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); 2 | const path = require('path'); 3 | const escape = require('escape-string-regexp'); 4 | const exclusionList = require('metro-config/src/defaults/exclusionList'); 5 | const pak = require('../package.json'); 6 | 7 | const root = path.resolve(__dirname, '..'); 8 | const modules = Object.keys({ ...pak.peerDependencies }); 9 | 10 | /** 11 | * Metro configuration 12 | * https://facebook.github.io/metro/docs/configuration 13 | * 14 | * @type {import('metro-config').MetroConfig} 15 | */ 16 | const config = { 17 | watchFolders: [root], 18 | 19 | // We need to make sure that only one version is loaded for peerDependencies 20 | // So we block them at the root, and alias them to the versions in example's node_modules 21 | resolver: { 22 | blacklistRE: exclusionList( 23 | modules.map( 24 | (m) => 25 | new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`) 26 | ) 27 | ), 28 | 29 | extraNodeModules: modules.reduce((acc, name) => { 30 | acc[name] = path.join(__dirname, 'node_modules', name); 31 | return acc; 32 | }, {}), 33 | }, 34 | 35 | transformer: { 36 | getTransformOptions: async () => ({ 37 | transform: { 38 | experimentalImportSupport: false, 39 | inlineRequires: true, 40 | }, 41 | }), 42 | }, 43 | }; 44 | 45 | module.exports = mergeConfig(getDefaultConfig(__dirname), config); 46 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-leveldb-example", 3 | "description": "Example app for react-native-leveldb", 4 | "version": "0.0.1", 5 | "private": true, 6 | "scripts": { 7 | "android": "react-native run-android", 8 | "ios": "react-native run-ios", 9 | "start": "react-native start" 10 | }, 11 | "dependencies": { 12 | "@react-native-async-storage/async-storage": "^1.18.2", 13 | "react": "18.2.0", 14 | "react-native": "0.72.7" 15 | }, 16 | "devDependencies": { 17 | "@babel/core": "^7.20.0", 18 | "@babel/runtime": "^7.20.0", 19 | "@react-native/metro-config": "^0.72.11", 20 | "babel-plugin-module-resolver": "^4.1.0", 21 | "metro-react-native-babel-preset": "^0.76.8" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/react-native.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | dependencies: { 5 | 'reactnativeleveldb': { 6 | root: path.join(__dirname, '..'), 7 | }, 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import {StyleSheet, View, Text} from 'react-native'; 3 | import { 4 | benchmarkAsyncStorage, 5 | benchmarkLeveldb, 6 | BenchmarkResults, 7 | BenchmarkResultsView 8 | } from "./benchmark"; 9 | import {leveldbExample, leveldbTests} from "./example"; 10 | 11 | interface BenchmarkState { 12 | leveldb?: BenchmarkResults; 13 | leveldbExample?: boolean; 14 | leveldbTests: string[]; 15 | asyncStorage?: BenchmarkResults; 16 | error?: string; 17 | } 18 | 19 | export default class App extends React.Component<{}, BenchmarkState> { 20 | state: BenchmarkState = {leveldbTests: []}; 21 | 22 | componentDidMount() { 23 | try { 24 | this.setState({ 25 | leveldb: benchmarkLeveldb(), 26 | leveldbExample: leveldbExample(), 27 | leveldbTests: leveldbTests(), 28 | }); 29 | 30 | benchmarkAsyncStorage().then(res => this.setState({asyncStorage: res})); 31 | } catch (e) { 32 | console.error('Error running benchmark:', e); 33 | } 34 | } 35 | 36 | render() { 37 | return ( 38 | 39 | Example validity: {this.state.leveldbExample == undefined ? '' : this.state.leveldbExample ? 'passed' : 'failed'} 40 | {this.state.leveldb && } 41 | {this.state.leveldbTests && this.state.leveldbTests.map((msg, idx) => 42 | Test: {msg} 43 | )} 44 | {this.state.asyncStorage && } 45 | {this.state.error && ERROR RUNNING: {this.state.error}} 46 | 47 | ); 48 | } 49 | } 50 | 51 | const styles = StyleSheet.create({ 52 | container: { 53 | flex: 1, 54 | justifyContent: 'center', 55 | }, 56 | }); 57 | -------------------------------------------------------------------------------- /example/src/benchmark.tsx: -------------------------------------------------------------------------------- 1 | import {LevelDB} from "react-native-leveldb"; 2 | import {Text} from "react-native"; 3 | import * as React from "react"; 4 | import AsyncStorage from "@react-native-async-storage/async-storage"; 5 | import {compareReadWrite, getRandomString, getTestSetArrayBuffer, getTestSetString} from "./test-util"; 6 | 7 | export interface BenchmarkResults { 8 | writeMany: { numKeys: number, durationMs: number } 9 | readMany: { numKeys: number, durationMs: number } 10 | } 11 | 12 | export function benchmarkLeveldb(): BenchmarkResults { 13 | let name = getRandomString(32) + '.db'; 14 | console.info('Opening DB', name); 15 | const db = new LevelDB(name, true, true); 16 | 17 | let res: Partial = {}; 18 | 19 | const writeKvs: [ArrayBuffer, ArrayBuffer][] = getTestSetArrayBuffer(10000); 20 | 21 | // === writeMany 22 | let started = new Date().getTime(); 23 | for (const [k, v] of writeKvs) { 24 | db.put(k, v); 25 | } 26 | res.writeMany = {numKeys: writeKvs.length, durationMs: new Date().getTime() - started}; 27 | 28 | // === readMany 29 | const readKvs: [ArrayBuffer, ArrayBuffer][] = []; 30 | started = new Date().getTime(); 31 | let it; 32 | for (it = db.newIterator().seekToFirst(); it.valid(); it.next()) { 33 | readKvs.push([it.keyBuf(), it.valueBuf()]); 34 | } 35 | it.close(); 36 | res.readMany = {numKeys: readKvs.length, durationMs: new Date().getTime() - started}; 37 | db.close(); 38 | 39 | compareReadWrite(writeKvs, readKvs); 40 | return res as BenchmarkResults; 41 | } 42 | 43 | export async function benchmarkAsyncStorage(): Promise { 44 | console.info('Clearing AsyncStorage'); 45 | try { 46 | await AsyncStorage.clear(); 47 | } catch (e: any) { 48 | if (!e?.message?.includes('Failed to delete storage directory')) { 49 | throw e; 50 | } 51 | } 52 | 53 | let res: Partial = {}; 54 | 55 | const writeKvs: [string, string][] = getTestSetString(10000); 56 | 57 | // === writeMany 58 | let started = new Date().getTime(); 59 | await AsyncStorage.multiSet(writeKvs); 60 | res.writeMany = {numKeys: writeKvs.length, durationMs: new Date().getTime() - started}; 61 | 62 | // === readMany 63 | started = new Date().getTime(); 64 | const readKvs = 65 | await AsyncStorage.multiGet(await AsyncStorage.getAllKeys()) as [string, string][]; 66 | res.readMany = {numKeys: readKvs.length, durationMs: new Date().getTime() - started}; 67 | 68 | compareReadWrite(writeKvs, readKvs); 69 | return res as BenchmarkResults; 70 | } 71 | 72 | export const BenchmarkResultsView = (x: BenchmarkResults & { title: string }) => { 73 | const {writeMany, readMany, title} = x; 74 | const writeManyRes = writeMany && 75 | `wrote ${writeMany.numKeys} items in ${writeMany.durationMs}ms; ` + 76 | `(${(writeMany.numKeys / writeMany.durationMs).toFixed(1)}items/ms)`; 77 | const readManyRes = readMany && 78 | `read ${readMany.numKeys} items in ${readMany.durationMs}ms; ` + 79 | `(${(readMany.numKeys / readMany.durationMs).toFixed(1)}items/ms)`; 80 | 81 | return (<> 82 | == {title} 83 | Benchmark write many: {writeManyRes} 84 | Benchmark read many: {readManyRes} 85 | ); 86 | } -------------------------------------------------------------------------------- /example/src/example.ts: -------------------------------------------------------------------------------- 1 | import {LevelDB} from "react-native-leveldb"; 2 | import {bufEquals, getRandomString} from "./test-util"; 3 | 4 | export function leveldbExample(): boolean { 5 | // Open a potentially new database. 6 | const name = 'example.db'; 7 | const createIfMissing = true; 8 | const errorIfExists = false; 9 | const db = new LevelDB(name, createIfMissing, errorIfExists); 10 | 11 | // Insert something into the database. Note that the key and the 12 | // value can either be strings or ArrayBuffers. 13 | // Strings are read & written in utf8. 14 | db.put('key', 'value'); 15 | 16 | // You can also use ArrayBuffers as input, containing binary data. 17 | const key = new Uint8Array([1, 2, 3]); 18 | const value = new Uint32Array([654321]); 19 | db.put(key.buffer, value.buffer); 20 | 21 | // Get values as string or as an ArrayBuffer (useful for binary data). 22 | const readStringValue = db.getStr('key'); 23 | const readBufferValue = new Uint32Array(db.getBuf(key.buffer)!); 24 | console.log(readStringValue, readBufferValue); // logs: value [654321] 25 | 26 | // Iterate over a range of values (here, from key "key" to the end.) 27 | let iter = db.newIterator(); 28 | for (iter.seek('key'); iter.valid(); iter.next()) { 29 | // There are also *Buf version to access iterators' keys & values. 30 | console.log(`iterating: "${iter.keyStr()}" / "${iter.valueStr()}"`); 31 | } 32 | 33 | // You need to close iterators when you are done with them. 34 | // Iterators will throw an error if used after this. 35 | iter.close(); 36 | 37 | db.close(); // Same for databases. 38 | 39 | return readStringValue == 'value' && 40 | readBufferValue.length == 1 && readBufferValue[0] == 654321; 41 | } 42 | 43 | export function leveldbTestMerge(batchMerge: boolean) { 44 | let nameDst = getRandomString(32) + '.db'; 45 | console.info('leveldbTestMerge: Opening DB', nameDst); 46 | const dbDst = new LevelDB(nameDst, true, true); 47 | dbDst.put('key1', 'value1'); 48 | dbDst.put('key2', 'value2'); 49 | 50 | const key3 = new Uint8Array([1, 2, 3]); 51 | const value3 = new Uint8Array([4, 5, 6]); 52 | dbDst.put(key3.buffer, value3.buffer); 53 | 54 | let nameSrc = getRandomString(32) + '.db'; 55 | console.info('leveldbTestMerge: Opening DB', nameSrc); 56 | const dbSrc = new LevelDB(nameSrc, true, true); 57 | dbSrc.put('keep', 'value'); 58 | dbSrc.put('key2', 'valueNew'); 59 | const value3New = new Uint8Array([7, 8, 9]); 60 | dbSrc.put(key3.buffer, value3New.buffer); 61 | 62 | dbDst.merge(dbSrc, batchMerge); 63 | dbSrc.close(); 64 | 65 | const errors: string[] = []; 66 | if (dbDst.getStr('key1') != 'value1') { 67 | errors.push(`key1 didn't have expected value: ${dbDst.getStr('key1')}`); 68 | } 69 | if (dbDst.getStr('key2') != 'valueNew') { 70 | errors.push(`key2 didn't have expected value: ${dbDst.getStr('key2')}`); 71 | } 72 | if (!bufEquals(dbDst.getBuf(key3.buffer)!, value3New)) { 73 | errors.push(`key3 (buf) didn't have expected value: ${new Uint8Array(dbDst.getBuf(key3.buffer)!)}`); 74 | } 75 | if (dbDst.getStr('keep') != 'value') { 76 | errors.push(`keep didn't have expected value: ${dbDst.getStr('keep')}`); 77 | } 78 | 79 | dbDst.close(); 80 | return errors; 81 | } 82 | 83 | export function leveldbTests() { 84 | let s: string[] = []; 85 | try { 86 | (global as any).leveldbTestException(); 87 | s.push('leveldbTestException: FAILED! No exception.'); 88 | } catch (e: any) { 89 | s.push('leveldbTestException: ' + e.message.slice(0, 20)); 90 | } 91 | 92 | try { 93 | (global as any).leveldbPut(-1); 94 | s.push('leveldbPut exception (out of range): FAILED! No exception.'); 95 | } catch (e: any) { 96 | s.push('leveldbPut exception (out of range): ' + e.message.slice(0, 100)); 97 | } 98 | 99 | try { 100 | const res = leveldbTestMerge(true); 101 | if (res.length) { 102 | s.push('leveldbTestMerge(true) failed with:' + res.join('; ')); 103 | } else { 104 | s.push('leveldbTestMerge(true) succeeded'); 105 | } 106 | } catch (e: any) { 107 | s.push('leveldbTestMerge(true) threw: ' + e.message); 108 | } 109 | 110 | try { 111 | const res = leveldbTestMerge(false); 112 | if (res.length) { 113 | s.push('leveldbTestMerge(false) failed with:' + res.join('; ')); 114 | } else { 115 | s.push('leveldbTestMerge(false) succeeded'); 116 | } 117 | } catch (e: any) { 118 | s.push('leveldbTestMerge(false) threw: ' + e.message); 119 | } 120 | 121 | return s; 122 | } 123 | -------------------------------------------------------------------------------- /example/src/test-util.tsx: -------------------------------------------------------------------------------- 1 | function getRandomArrayBuffer(size: number): ArrayBuffer { 2 | const buffer = new ArrayBuffer(size); 3 | const view = new Uint8Array(buffer); 4 | for (let i = 0; i < size; ++i) { 5 | view[i] = Math.random() * 256; 6 | } 7 | return buffer; 8 | } 9 | 10 | export function getTestSetArrayBuffer(length: number) { 11 | const writeKvs: [ArrayBuffer, ArrayBuffer][] = []; 12 | for (let i = 0; i < length; ++i) { 13 | writeKvs.push([getRandomArrayBuffer(32), getRandomArrayBuffer(1024)]); 14 | } 15 | 16 | return writeKvs; 17 | } 18 | 19 | const alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-'; 20 | 21 | export function getRandomString(size: number): string { 22 | let buffer = ''; 23 | for (let i = 0; i < size; ++i) { 24 | buffer += alphabet[Math.floor(Math.random() * alphabet.length)]; 25 | } 26 | 27 | return buffer; 28 | } 29 | 30 | export function getTestSetString(length: number) { 31 | const writeKvs: [string, string][] = []; 32 | for (let i = 0; i < length; ++i) { 33 | writeKvs.push([getRandomString(32), getRandomString(1024)]); 34 | } 35 | 36 | return writeKvs; 37 | } 38 | 39 | export function compareReadWrite(writeKvs: [T, T][], readKvs: [T, T][]) { 40 | if (readKvs.length != writeKvs.length) { 41 | throw new Error(`benchmark: expected ${writeKvs.length} KVs; got: ${readKvs.length}`); 42 | } 43 | } 44 | 45 | export function bufEquals(a_: ArrayBuffer, b_: ArrayBuffer) { 46 | const a = new Uint8Array(a_), b = new Uint8Array(b_); 47 | if (a.length != a.length) { 48 | return false; 49 | } 50 | 51 | for (let i = 0; i < a.length; ++i) { 52 | if (a[i]!= b[i]) { 53 | return false; 54 | } 55 | } 56 | 57 | return true; 58 | } -------------------------------------------------------------------------------- /ios/Leveldb.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "react-native-leveldb.h" 4 | 5 | @interface Leveldb : NSObject 6 | 7 | @property (nonatomic, assign) BOOL setBridgeOnMainQueue; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /ios/Leveldb.mm: -------------------------------------------------------------------------------- 1 | #import "Leveldb.h" 2 | #import 3 | #import 4 | #import "react-native-leveldb.h" 5 | 6 | using namespace facebook; 7 | 8 | @implementation Leveldb 9 | @synthesize bridge = _bridge; 10 | @synthesize methodQueue = _methodQueue; 11 | 12 | RCT_EXPORT_MODULE(Leveldb) 13 | 14 | RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) 15 | { 16 | NSLog(@"Installing Leveldb bindings..."); 17 | RCTBridge *bridge = [RCTBridge currentBridge]; 18 | RCTCxxBridge *cxxBridge = (RCTCxxBridge *) bridge; 19 | if (cxxBridge == nil) { 20 | return @false; 21 | } 22 | if (cxxBridge.runtime == nil) { 23 | return @false; 24 | } 25 | NSURL *docPath = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]; 26 | installLeveldb(*(jsi::Runtime *)cxxBridge.runtime, std::string([[docPath path] UTF8String])); 27 | return @true; 28 | } 29 | 30 | - (void)invalidate { 31 | cleanupLeveldb(); 32 | } 33 | 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /ios/Leveldb.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 11 | 5E46D8CD2428F78900513E24 /* example.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E46D8CB2428F78900513E24 /* example.cpp */; }; 12 | 5E555C0D2413F4C50049A1A2 /* Leveldb.mm in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* Leveldb.mm */; }; 13 | 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXCopyFilesBuildPhase section */ 17 | 58B511D91A9E6C8500147676 /* CopyFiles */ = { 18 | isa = PBXCopyFilesBuildPhase; 19 | buildActionMask = 2147483647; 20 | dstPath = "include/$(PRODUCT_NAME)"; 21 | dstSubfolderSpec = 16; 22 | files = ( 23 | ); 24 | runOnlyForDeploymentPostprocessing = 0; 25 | }; 26 | /* End PBXCopyFilesBuildPhase section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 134814201AA4EA6300B7C361 /* libLeveldb.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libLeveldb.a; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | 31 | 5E46D8CB2428F78900513E24 /* example.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = example.cpp; path = ../cpp/example.cpp; sourceTree = ""; }; 32 | 5E46D8CC2428F78900513E24 /* example.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = example.h; path = ../cpp/example.h; sourceTree = ""; }; 33 | B3E7B5891CC2AC0600A0062D /* Leveldb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Leveldb.mm; sourceTree = ""; }; 34 | 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | 58B511D81A9E6C8500147676 /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | ); 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | /* End PBXFrameworksBuildPhase section */ 46 | 47 | /* Begin PBXGroup section */ 48 | 134814211AA4EA7D00B7C361 /* Products */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 134814201AA4EA6300B7C361 /* libLeveldb.a */, 52 | ); 53 | name = Products; 54 | sourceTree = ""; 55 | }; 56 | 58B511D21A9E6C8500147676 = { 57 | isa = PBXGroup; 58 | children = ( 59 | 60 | 5E46D8CB2428F78900513E24 /* example.cpp */, 61 | 5E46D8CC2428F78900513E24 /* example.h */, 62 | B3E7B5891CC2AC0600A0062D /* Leveldb.mm */, 63 | 64 | 134814211AA4EA7D00B7C361 /* Products */, 65 | ); 66 | sourceTree = ""; 67 | }; 68 | /* End PBXGroup section */ 69 | 70 | /* Begin PBXNativeTarget section */ 71 | 58B511DA1A9E6C8500147676 /* Leveldb */ = { 72 | isa = PBXNativeTarget; 73 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "Leveldb" */; 74 | buildPhases = ( 75 | 58B511D71A9E6C8500147676 /* Sources */, 76 | 58B511D81A9E6C8500147676 /* Frameworks */, 77 | 58B511D91A9E6C8500147676 /* CopyFiles */, 78 | ); 79 | buildRules = ( 80 | ); 81 | dependencies = ( 82 | ); 83 | name = Leveldb; 84 | productName = RCTDataManager; 85 | productReference = 134814201AA4EA6300B7C361 /* libLeveldb.a */; 86 | productType = "com.apple.product-type.library.static"; 87 | }; 88 | /* End PBXNativeTarget section */ 89 | 90 | /* Begin PBXProject section */ 91 | 58B511D31A9E6C8500147676 /* Project object */ = { 92 | isa = PBXProject; 93 | attributes = { 94 | LastUpgradeCheck = 0920; 95 | ORGANIZATIONNAME = Facebook; 96 | TargetAttributes = { 97 | 58B511DA1A9E6C8500147676 = { 98 | CreatedOnToolsVersion = 6.1.1; 99 | }; 100 | }; 101 | }; 102 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "Leveldb" */; 103 | compatibilityVersion = "Xcode 3.2"; 104 | developmentRegion = English; 105 | hasScannedForEncodings = 0; 106 | knownRegions = ( 107 | English, 108 | en, 109 | ); 110 | mainGroup = 58B511D21A9E6C8500147676; 111 | productRefGroup = 58B511D21A9E6C8500147676; 112 | projectDirPath = ""; 113 | projectRoot = ""; 114 | targets = ( 115 | 58B511DA1A9E6C8500147676 /* Leveldb */, 116 | ); 117 | }; 118 | /* End PBXProject section */ 119 | 120 | /* Begin PBXSourcesBuildPhase section */ 121 | 58B511D71A9E6C8500147676 /* Sources */ = { 122 | isa = PBXSourcesBuildPhase; 123 | buildActionMask = 2147483647; 124 | files = ( 125 | 126 | 5E46D8CD2428F78900513E24 /* example.cpp in Sources */, 127 | 5E555C0D2413F4C50049A1A2 /* Leveldb.mm in Sources */, 128 | 129 | ); 130 | runOnlyForDeploymentPostprocessing = 0; 131 | }; 132 | /* End PBXSourcesBuildPhase section */ 133 | 134 | /* Begin XCBuildConfiguration section */ 135 | 58B511ED1A9E6C8500147676 /* Debug */ = { 136 | isa = XCBuildConfiguration; 137 | buildSettings = { 138 | ALWAYS_SEARCH_USER_PATHS = NO; 139 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 140 | CLANG_CXX_LIBRARY = "libc++"; 141 | CLANG_ENABLE_MODULES = YES; 142 | CLANG_ENABLE_OBJC_ARC = YES; 143 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 144 | CLANG_WARN_BOOL_CONVERSION = YES; 145 | CLANG_WARN_COMMA = YES; 146 | CLANG_WARN_CONSTANT_CONVERSION = YES; 147 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 148 | CLANG_WARN_EMPTY_BODY = YES; 149 | CLANG_WARN_ENUM_CONVERSION = YES; 150 | CLANG_WARN_INFINITE_RECURSION = YES; 151 | CLANG_WARN_INT_CONVERSION = YES; 152 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 153 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 154 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 155 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 156 | CLANG_WARN_STRICT_PROTOTYPES = YES; 157 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 158 | CLANG_WARN_UNREACHABLE_CODE = YES; 159 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 160 | COPY_PHASE_STRIP = NO; 161 | ENABLE_STRICT_OBJC_MSGSEND = YES; 162 | ENABLE_TESTABILITY = YES; 163 | "EXCLUDED_ARCHS[sdk=*]" = arm64; 164 | GCC_C_LANGUAGE_STANDARD = gnu99; 165 | GCC_DYNAMIC_NO_PIC = NO; 166 | GCC_NO_COMMON_BLOCKS = YES; 167 | GCC_OPTIMIZATION_LEVEL = 0; 168 | GCC_PREPROCESSOR_DEFINITIONS = ( 169 | "DEBUG=1", 170 | "$(inherited)", 171 | ); 172 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 173 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 174 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 175 | GCC_WARN_UNDECLARED_SELECTOR = YES; 176 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 177 | GCC_WARN_UNUSED_FUNCTION = YES; 178 | GCC_WARN_UNUSED_VARIABLE = YES; 179 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 180 | MTL_ENABLE_DEBUG_INFO = YES; 181 | ONLY_ACTIVE_ARCH = YES; 182 | SDKROOT = iphoneos; 183 | }; 184 | name = Debug; 185 | }; 186 | 58B511EE1A9E6C8500147676 /* Release */ = { 187 | isa = XCBuildConfiguration; 188 | buildSettings = { 189 | ALWAYS_SEARCH_USER_PATHS = NO; 190 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 191 | CLANG_CXX_LIBRARY = "libc++"; 192 | CLANG_ENABLE_MODULES = YES; 193 | CLANG_ENABLE_OBJC_ARC = YES; 194 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 195 | CLANG_WARN_BOOL_CONVERSION = YES; 196 | CLANG_WARN_COMMA = YES; 197 | CLANG_WARN_CONSTANT_CONVERSION = YES; 198 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 199 | CLANG_WARN_EMPTY_BODY = YES; 200 | CLANG_WARN_ENUM_CONVERSION = YES; 201 | CLANG_WARN_INFINITE_RECURSION = YES; 202 | CLANG_WARN_INT_CONVERSION = YES; 203 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 204 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 205 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 206 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 207 | CLANG_WARN_STRICT_PROTOTYPES = YES; 208 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 209 | CLANG_WARN_UNREACHABLE_CODE = YES; 210 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 211 | COPY_PHASE_STRIP = YES; 212 | ENABLE_NS_ASSERTIONS = NO; 213 | ENABLE_STRICT_OBJC_MSGSEND = YES; 214 | "EXCLUDED_ARCHS[sdk=*]" = arm64; 215 | GCC_C_LANGUAGE_STANDARD = gnu99; 216 | GCC_NO_COMMON_BLOCKS = YES; 217 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 218 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 219 | GCC_WARN_UNDECLARED_SELECTOR = YES; 220 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 221 | GCC_WARN_UNUSED_FUNCTION = YES; 222 | GCC_WARN_UNUSED_VARIABLE = YES; 223 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 224 | MTL_ENABLE_DEBUG_INFO = NO; 225 | SDKROOT = iphoneos; 226 | VALIDATE_PRODUCT = YES; 227 | }; 228 | name = Release; 229 | }; 230 | 58B511F01A9E6C8500147676 /* Debug */ = { 231 | isa = XCBuildConfiguration; 232 | buildSettings = { 233 | HEADER_SEARCH_PATHS = ( 234 | "$(inherited)", 235 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 236 | "$(SRCROOT)/../../../React/**", 237 | "$(SRCROOT)/../../react-native/React/**", 238 | ); 239 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 240 | OTHER_LDFLAGS = "-ObjC"; 241 | PRODUCT_NAME = Leveldb; 242 | SKIP_INSTALL = YES; 243 | 244 | }; 245 | name = Debug; 246 | }; 247 | 58B511F11A9E6C8500147676 /* Release */ = { 248 | isa = XCBuildConfiguration; 249 | buildSettings = { 250 | HEADER_SEARCH_PATHS = ( 251 | "$(inherited)", 252 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 253 | "$(SRCROOT)/../../../React/**", 254 | "$(SRCROOT)/../../react-native/React/**", 255 | ); 256 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 257 | OTHER_LDFLAGS = "-ObjC"; 258 | PRODUCT_NAME = Leveldb; 259 | SKIP_INSTALL = YES; 260 | 261 | }; 262 | name = Release; 263 | }; 264 | /* End XCBuildConfiguration section */ 265 | 266 | /* Begin XCConfigurationList section */ 267 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "Leveldb" */ = { 268 | isa = XCConfigurationList; 269 | buildConfigurations = ( 270 | 58B511ED1A9E6C8500147676 /* Debug */, 271 | 58B511EE1A9E6C8500147676 /* Release */, 272 | ); 273 | defaultConfigurationIsVisible = 0; 274 | defaultConfigurationName = Release; 275 | }; 276 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "Leveldb" */ = { 277 | isa = XCConfigurationList; 278 | buildConfigurations = ( 279 | 58B511F01A9E6C8500147676 /* Debug */, 280 | 58B511F11A9E6C8500147676 /* Release */, 281 | ); 282 | defaultConfigurationIsVisible = 0; 283 | defaultConfigurationName = Release; 284 | }; 285 | /* End XCConfigurationList section */ 286 | }; 287 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 288 | } 289 | -------------------------------------------------------------------------------- /lefthook.yml: -------------------------------------------------------------------------------- 1 | pre-commit: 2 | parallel: true 3 | commands: 4 | lint: 5 | files: git diff --name-only @{push} 6 | glob: "*.{js,ts,jsx,tsx}" 7 | run: npx eslint {files} 8 | types: 9 | files: git diff --name-only @{push} 10 | glob: "*.{js,ts, jsx, tsx}" 11 | run: npx tsc --noEmit 12 | commit-msg: 13 | parallel: true 14 | commands: 15 | commitlint: 16 | run: npx commitlint --edit 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-leveldb", 3 | "version": "3.6.0", 4 | "description": "Superfast React Native bindings for LevelDB", 5 | "main": "lib/commonjs/index", 6 | "module": "lib/module/index", 7 | "types": "lib/typescript/index.d.ts", 8 | "react-native": "src/index", 9 | "source": "src/index", 10 | "files": [ 11 | "src", 12 | "lib", 13 | "android", 14 | "ios", 15 | "cpp", 16 | "react-native-leveldb.podspec", 17 | "!lib/typescript/example", 18 | "!android/build", 19 | "!android/.cxx", 20 | "!android/cmake-build-debug", 21 | "!ios/build", 22 | "!**/__tests__", 23 | "!**/__fixtures__", 24 | "!**/__mocks__", 25 | "!**/.DS_Store", 26 | "!**/*savv*" 27 | ], 28 | "scripts": { 29 | "test": "jest", 30 | "typescript": "tsc --noEmit", 31 | "lint": "eslint \"**/*.{js,ts,tsx}\"", 32 | "prepare": "bob build", 33 | "release": "release-it", 34 | "example": "yarn --cwd example", 35 | "pods": "cd example && pod-install --quiet", 36 | "bootstrap": "git submodule update --init --recursive && yarn example && yarn && yarn pods" 37 | }, 38 | "keywords": [ 39 | "react-native", 40 | "ios", 41 | "android" 42 | ], 43 | "repository": "https://github.com/greentriangle/react-native-leveldb", 44 | "author": "GreenTriangle (https://github.com/greentriangle)", 45 | "license": "MIT", 46 | "bugs": { 47 | "url": "https://github.com/greentriangle/react-native-leveldb/issues" 48 | }, 49 | "homepage": "https://github.com/greentriangle/react-native-leveldb#readme", 50 | "publishConfig": { 51 | "registry": "https://registry.npmjs.org/" 52 | }, 53 | "devDependencies": { 54 | "@arkweid/lefthook": "^0.7.7", 55 | "@babel/eslint-parser": "^7.20.0", 56 | "@commitlint/config-conventional": "^17.0.2", 57 | "@react-native/eslint-config": "^0.72.2", 58 | "@release-it/conventional-changelog": "^5.0.0", 59 | "@tsconfig/react-native": "^3.0.0", 60 | "@types/jest": "^29.2.1", 61 | "@types/react": "~18.0.24", 62 | "@types/react-native": "0.70.0", 63 | "commitlint": "^17.0.2", 64 | "eslint": "^8.4.1", 65 | "eslint-config-prettier": "^8.5.0", 66 | "eslint-plugin-prettier": "^4.0.0", 67 | "jest": "^29.2.1", 68 | "pod-install": "^0.1.0", 69 | "prettier": "^2.4.1", 70 | "react": "18.2.0", 71 | "react-native": "0.72.7", 72 | "react-native-builder-bob": "^0.18.2", 73 | "release-it": "^15.0.0", 74 | "typescript": "^4.8.4", 75 | "metro-react-native-babel-preset": "^0.76.8" 76 | }, 77 | "resolutions": { 78 | "@types/react": "17.0.21" 79 | }, 80 | "peerDependencies": { 81 | "react": "*", 82 | "react-native": "*" 83 | }, 84 | "jest": { 85 | "preset": "react-native", 86 | "modulePathIgnorePatterns": [ 87 | "/example/node_modules", 88 | "/lib/" 89 | ] 90 | }, 91 | "release-it": { 92 | "git": { 93 | "commitMessage": "chore: release ${version}", 94 | "tagName": "v${version}" 95 | }, 96 | "npm": { 97 | "publish": true 98 | }, 99 | "github": { 100 | "release": true 101 | }, 102 | "plugins": { 103 | "@release-it/conventional-changelog": { 104 | "preset": "angular" 105 | } 106 | } 107 | }, 108 | "eslintConfig": { 109 | "root": true, 110 | "parser": "@babel/eslint-parser", 111 | "extends": [ 112 | "@react-native-community", 113 | "prettier" 114 | ], 115 | "rules": { 116 | "prettier/prettier": [ 117 | "error", 118 | { 119 | "quoteProps": "consistent", 120 | "singleQuote": true, 121 | "tabWidth": 2, 122 | "trailingComma": "es5", 123 | "useTabs": false 124 | } 125 | ] 126 | } 127 | }, 128 | "eslintIgnore": [ 129 | "node_modules/", 130 | "lib/" 131 | ], 132 | "prettier": { 133 | "quoteProps": "consistent", 134 | "singleQuote": true, 135 | "tabWidth": 2, 136 | "trailingComma": "es5", 137 | "useTabs": false 138 | }, 139 | "react-native-builder-bob": { 140 | "source": "src", 141 | "output": "lib", 142 | "targets": [ 143 | "commonjs", 144 | "module", 145 | [ 146 | "typescript", 147 | { 148 | "project": "tsconfig.build.json" 149 | } 150 | ] 151 | ] 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /react-native-leveldb.podspec: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = "react-native-leveldb" 7 | s.version = package["version"] 8 | s.summary = package["description"] 9 | s.homepage = package["homepage"] 10 | s.license = package["license"] 11 | s.authors = package["author"] 12 | 13 | s.platforms = { :ios => "11.0" } 14 | s.source = { :git => "https://github.com/greentriangle/react-native-leveldb.git", :tag => "#{s.version}" } 15 | 16 | s.pod_target_xcconfig = { 17 | :GCC_PREPROCESSOR_DEFINITIONS => "LEVELDB_IS_BIG_ENDIAN=0 LEVELDB_PLATFORM_POSIX HAVE_FULLFSYNC=1", 18 | :HEADER_SEARCH_PATHS => "\"${PROJECT_DIR}/Headers/Public/react-native-leveldb/leveldb/include/\" \"${PROJECT_DIR}/Headers/Public/react-native-leveldb/leveldb/\"", 19 | :WARNING_CFLAGS => "-Wno-shorten-64-to-32 -Wno-comma -Wno-unreachable-code -Wno-conditional-uninitialized -Wno-deprecated-declarations", 20 | :USE_HEADERMAP => "No" 21 | } 22 | 23 | s.header_mappings_dir = "cpp" 24 | s.source_files = "ios/**/*.{h,m,mm}", "cpp/*.{h,cpp}", "cpp/leveldb/db/*.{cc,h}", "cpp/leveldb/port/*.{cc,h}", "cpp/leveldb/table/*.{cc,h}", "cpp/leveldb/util/*.{cc,h}", "cpp/leveldb/include/leveldb/*.h" 25 | s.exclude_files = "cpp/leveldb/**/*_test.cc", "cpp/leveldb/**/*_bench.cc", "cpp/leveldb/db/leveldbutil.cc", "cpp/leveldb/util/env_windows.cc", "cpp/leveldb/util/testutil.cc" 26 | 27 | s.dependency "React-Core" 28 | end 29 | -------------------------------------------------------------------------------- /scripts/bootstrap.js: -------------------------------------------------------------------------------- 1 | const os = require('os'); 2 | const path = require('path'); 3 | const child_process = require('child_process'); 4 | 5 | const root = path.resolve(__dirname, '..'); 6 | const args = process.argv.slice(2); 7 | const options = { 8 | cwd: process.cwd(), 9 | env: process.env, 10 | stdio: 'inherit', 11 | encoding: 'utf-8', 12 | }; 13 | 14 | if (os.type() === 'Windows_NT') { 15 | options.shell = true; 16 | } 17 | 18 | let result; 19 | 20 | if (process.cwd() !== root || args.length) { 21 | // We're not in the root of the project, or additional arguments were passed 22 | // In this case, forward the command to `yarn` 23 | result = child_process.spawnSync('yarn', args, options); 24 | } else { 25 | // If `yarn` is run without arguments, perform bootstrap 26 | result = child_process.spawnSync('yarn', ['bootstrap'], options); 27 | } 28 | 29 | process.exitCode = result.status; 30 | -------------------------------------------------------------------------------- /src/fake.test.ts: -------------------------------------------------------------------------------- 1 | import {arraybufGt, FakeLevelDB, toArraybuf, toString} from "./fake"; 2 | 3 | test('arraybufGt', () => { 4 | expect(arraybufGt(toArraybuf('dbMeta'), toArraybuf('dbMeta'))).toEqual(false); 5 | expect(arraybufGt(toArraybuf('db.farm'), toArraybuf('dbMeta'))).toEqual(false); 6 | expect(arraybufGt(toArraybuf('dbMeta'), toArraybuf('db.farm'))).toEqual(true); 7 | expect(arraybufGt(toArraybuf('dbMeta'), toArraybuf('dbMetaverse'))).toEqual(false); 8 | expect(arraybufGt(toArraybuf('dbMetaverse'), toArraybuf('dbMeta'))).toEqual(true); 9 | 10 | expect(toString(toArraybuf('dbMeta'))).toEqual('dbMeta'); 11 | }); 12 | 13 | 14 | test('FakeLevelDB', () => { 15 | const db = new FakeLevelDB(); 16 | db.put('dbMeta', 'a'); 17 | expect(db.kv?.map(x => [toString(x[0]), toString(x[1])])).toEqual([['dbMeta', 'a']]); 18 | 19 | db.put('dbMeta', 'b'); 20 | expect(db.kv?.map(x => [toString(x[0]), toString(x[1])])).toEqual([['dbMeta', 'b']]); 21 | 22 | db.put('db.farm.1', 'c'); 23 | expect(db.kv?.map(x => toString(x[0]))).toEqual(['db.farm.1', 'dbMeta']) 24 | 25 | db.put('dbMeta', 'd'); 26 | expect(db.kv?.map(x => toString(x[0]))).toEqual(['db.farm.1', 'dbMeta']); 27 | 28 | db.put('db.farm.0', 'e'); 29 | expect(db.kv?.map(x => toString(x[0]))).toEqual(['db.farm.0', 'db.farm.1', 'dbMeta']) 30 | 31 | db.put('dbMeta', 'f'); 32 | expect(db.kv?.map(x => toString(x[0]))).toEqual(['db.farm.0', 'db.farm.1', 'dbMeta']) 33 | 34 | db.put('dbMetaverse', 'g'); 35 | expect(db.kv?.map(x => toString(x[0]))).toEqual(['db.farm.0', 'db.farm.1', 'dbMeta', 'dbMetaverse']) 36 | expect(db.getStr('dbMeta')).toEqual('f'); 37 | }); 38 | -------------------------------------------------------------------------------- /src/fake.ts: -------------------------------------------------------------------------------- 1 | import type { LevelDBI, LevelDBIteratorI } from "./index"; 2 | 3 | // Return the position at the first key in the source that is at or past `k`. 4 | function getIdx(kv: null | [ArrayBuffer, ArrayBuffer][], k: ArrayBuffer | string, start?: number, end?: number): number { 5 | if (!kv) { 6 | throw new Error('FakeLevelDB was closed!'); 7 | } 8 | 9 | k = toArraybuf(k); 10 | start = start || 0; 11 | end = end || kv.length; 12 | 13 | const pivot: number = Math.floor(start + (end - start) / 2); 14 | if (end - start <= 1) { 15 | if (pivot < kv.length && arraybufGt(k, kv[pivot]![0])) { 16 | return end; 17 | } else { 18 | return pivot; 19 | } 20 | } 21 | if (!arraybufGt(kv[pivot]![0], k) && !arraybufGt(k, kv[pivot]![0])) { // equality check, done as the inverse of <> 22 | return pivot; 23 | } 24 | if (arraybufGt(kv[pivot]![0], k)) { 25 | return getIdx(kv, k, start, pivot); 26 | } else { 27 | return getIdx(kv, k, pivot, end); 28 | } 29 | } 30 | 31 | export class FakeLevelDBIterator implements LevelDBIteratorI { 32 | private kv: [ArrayBuffer, ArrayBuffer][]; 33 | private pos: undefined | number; 34 | 35 | constructor(db: FakeLevelDB) { 36 | if (!db.kv) { 37 | throw new Error(`Could't make FakeLevelDBIterator: DB was closed!`); 38 | } 39 | 40 | this.kv = [...db.kv]; // This creates a snapshot, like LevelDB would! 41 | this.pos = undefined; 42 | } 43 | 44 | seekToFirst(): LevelDBIteratorI { 45 | this.pos = 0; 46 | return this; 47 | } 48 | 49 | seekLast(): LevelDBIteratorI { 50 | this.pos = this.kv.length - 1; 51 | return this; 52 | } 53 | 54 | seek(target: ArrayBuffer | string): LevelDBIteratorI { 55 | this.pos = getIdx(this.kv, target); 56 | return this; 57 | } 58 | 59 | valid(): boolean { 60 | return this.pos !== undefined && this.pos >= 0 && this.pos < this.kv.length; 61 | } 62 | 63 | next(): void { 64 | this.pos!++; 65 | } 66 | 67 | prev(): void { 68 | this.pos!--; 69 | } 70 | 71 | close() { 72 | this.pos = undefined; 73 | } 74 | 75 | keyStr(): string { 76 | return toString(this.kv[this.pos!]![0]); 77 | } 78 | 79 | keyBuf(): ArrayBuffer { 80 | return toArraybuf(this.kv[this.pos!]![0]); 81 | } 82 | 83 | valueStr(): string { 84 | return toString(this.kv[this.pos!]![1]); 85 | } 86 | 87 | valueBuf(): ArrayBuffer { 88 | return toArraybuf(this.kv[this.pos!]![1]); 89 | } 90 | compareKey(target: string | ArrayBuffer): number { 91 | const arrTarget = toArraybuf(target); 92 | return (arraybufGt(this.kv[this.pos!]![0], arrTarget) ? 1 : arraybufLt(this.kv[this.pos!]![0], target as ArrayBuffer) ? -1 : 0); 93 | } 94 | } 95 | 96 | // `global as any` is a hack to get around this issue: 97 | // https://github.com/microsoft/TypeScript/issues/31535 98 | var decoder = new (global as any).TextDecoder(); 99 | var encoder = new (global as any).TextEncoder(); 100 | 101 | export function toString(buf: string | ArrayBuffer): string { 102 | if (typeof buf == 'string') { 103 | return buf; 104 | } 105 | 106 | return decoder.decode(new Uint8Array(buf)); 107 | } 108 | 109 | export function toArraybuf(str: string | ArrayBuffer): ArrayBuffer { 110 | if (str instanceof ArrayBuffer) { 111 | return str; 112 | } 113 | var uint8Arr: Uint8Array = encoder.encode(str); 114 | return uint8Arr.buffer; 115 | } 116 | 117 | export function arraybufGt(a: ArrayBuffer, b: ArrayBuffer): boolean { 118 | var keyA = new Uint8Array(a); 119 | var keyB = new Uint8Array(b); 120 | for (var i = 0; i < keyA.byteLength && i < keyB.byteLength; ++i) { 121 | if (keyA[i]! > keyB[i]!) { 122 | return true; 123 | } 124 | if (keyA[i]! < keyB[i]!) { 125 | return false; 126 | } 127 | } 128 | 129 | return keyA.byteLength > keyB.byteLength; 130 | } 131 | export function arraybufLt(a: ArrayBuffer, b: ArrayBuffer): boolean { 132 | var keyA = new Uint8Array(a); 133 | var keyB = new Uint8Array(b); 134 | for (var i = 0; i < keyA.byteLength && i < keyB.byteLength; ++i) { 135 | if (keyA[i]! < keyB[i]!) { 136 | return true; 137 | } 138 | if (keyA[i]! > keyB[i]!) { 139 | return false; 140 | } 141 | } 142 | 143 | return keyA.byteLength < keyB.byteLength; 144 | } 145 | 146 | 147 | export class FakeLevelDB implements LevelDBI { 148 | // The in-mem storage, as a sorted Array of KVs. The keys & values are stored as ArrayBuffers, which has the advantage 149 | // that it's very close to how LevelDB works. 150 | public kv: null | [ArrayBuffer, ArrayBuffer][]; 151 | 152 | constructor() { 153 | this.kv = []; 154 | } 155 | 156 | close() { 157 | this.kv = null; 158 | } 159 | 160 | closed() { 161 | return this.kv == null; 162 | } 163 | 164 | put(k: ArrayBuffer | string, v: ArrayBuffer | string) { 165 | const curIdx = getIdx(this.kv, k); 166 | // curIdx is the position at the first key in the source that is at or past `k`: 167 | if (curIdx == this.kv!.length) { 168 | this.kv!.push([toArraybuf(k), toArraybuf(v)]); 169 | } else if (arraybufGt(this.kv![curIdx]![0], toArraybuf(k))) { 170 | // When curIdx's key is past `k`, we add a new element at position. For example, given keys b, d, f: 171 | // k='a' should return 0; k='c' should return 1; k='f' should return 3. 172 | this.kv!.splice(curIdx, 0, [toArraybuf(k), toArraybuf(v)]); 173 | } else { 174 | this.kv![curIdx]![1] = toArraybuf(v); 175 | } 176 | } 177 | 178 | delete(k: ArrayBuffer | string) { 179 | k = toArraybuf(k); 180 | const curIdx = getIdx(this.kv, k); 181 | if (curIdx < this.kv!.length && !arraybufGt(this.kv![curIdx]![0], k) && !arraybufGt(k, this.kv![curIdx]![0])) { 182 | this.kv!.splice(curIdx, 1); 183 | } 184 | } 185 | 186 | getStr(k: ArrayBuffer | string): null | string { 187 | const buf = this.getBuf(k); 188 | return buf && toString(buf); 189 | } 190 | 191 | getBuf(k: ArrayBuffer | string): null | ArrayBuffer { 192 | k = toArraybuf(k); 193 | const curIdx = getIdx(this.kv, k); 194 | const kv = curIdx < this.kv!.length ? this.kv![curIdx] : null; 195 | return !kv || arraybufGt(kv[0], k) || arraybufGt(k, kv[0]) ? null : kv[1]; 196 | } 197 | 198 | newIterator(): LevelDBIteratorI { 199 | return new FakeLevelDBIterator(this); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { NativeModules } from 'react-native'; 2 | 3 | let nativeModuleInitError: null|string = null; 4 | const LeveldbModule = NativeModules.Leveldb; 5 | if (LeveldbModule == null || typeof LeveldbModule.install !== 'function') { 6 | nativeModuleInitError = 'The native Leveldb module could not be found! Is it correctly installed and autolinked?'; 7 | } 8 | 9 | // Call the synchronous blocking install() function 10 | try { 11 | if (LeveldbModule.install() !== true) { 12 | nativeModuleInitError = 'The native Leveldb JSI bindings could not be installed!'; 13 | } 14 | } catch (e) { 15 | nativeModuleInitError = e instanceof Error ? e?.message : 'Leveldb.install caught error!'; 16 | } 17 | 18 | const g = global as any; 19 | 20 | export interface LevelDBIteratorI { 21 | // Position at the first key in the source. The iterator is Valid() 22 | // after this call iff the source is not empty. 23 | seekToFirst(): LevelDBIteratorI; 24 | 25 | // Position at the last key in the source. The iterator is 26 | // Valid() after this call iff the source is not empty. 27 | seekLast(): LevelDBIteratorI; 28 | 29 | // Position at the first key in the source that is at or past target. 30 | // The iterator is Valid() after this call iff the source contains 31 | // an entry that comes at or past target. 32 | seek(target: ArrayBuffer | string): LevelDBIteratorI; 33 | 34 | // An iterator is either positioned at a key/value pair, or 35 | // not valid. This method returns true iff the iterator is valid. 36 | valid(): boolean; 37 | 38 | // Moves to the next entry in the source. After this call, Valid() is 39 | // true iff the iterator was not positioned at the last entry in the source. 40 | // REQUIRES: Valid() 41 | next(): void; 42 | 43 | // Moves to the previous entry in the source. After this call, Valid() is 44 | // true iff the iterator was not positioned at the first entry in source. 45 | // REQUIRES: Valid() 46 | prev(): void; 47 | close(): void; 48 | 49 | // Return the key for the current entry. The underlying storage for 50 | // the returned slice is valid only until the next modification of 51 | // the iterator. 52 | // REQUIRES: Valid() 53 | keyStr(): string; 54 | keyBuf(): ArrayBuffer; 55 | 56 | // Return the value for the current entry. The underlying storage for 57 | // the returned slice is valid only until the next modification of 58 | // the iterator. 59 | // REQUIRES: Valid() 60 | valueStr(): string; 61 | valueBuf(): ArrayBuffer; 62 | 63 | /** 64 | * Executes a comparison using the underlying iterator's Compare(Slice ...) method 65 | * @param target 66 | */ 67 | compareKey(target: ArrayBuffer | string): number; 68 | } 69 | 70 | export interface LevelDBI { 71 | // Close this ref to LevelDB. 72 | close(): void; 73 | 74 | // Returns true if this ref to LevelDB is closed. This can happen if close() is called on *any* open reference to a 75 | // given LevelDB name. 76 | closed(): boolean; 77 | 78 | // Set the database entry for "k" to "v". Returns OK on success, throws an exception on error. 79 | put(k: ArrayBuffer | string, v: ArrayBuffer | string): void; 80 | 81 | // Remove the database entry (if any) for "key". Throws an exception on error. 82 | // It is not an error if "key" did not exist in the database. 83 | delete(k: ArrayBuffer | string): void; 84 | 85 | // Returns the corresponding value for "key", if the database contains it; returns null otherwise. 86 | // Throws an exception if there is an error. 87 | // The *Str and *Buf methods help with geting the underlying data as a utf8 string or a byte buffer. 88 | getStr(k: ArrayBuffer | string): null | string; 89 | getBuf(k: ArrayBuffer | string): null | ArrayBuffer; 90 | 91 | // Returns an iterator over the contents of the database. 92 | // The result of newIterator() is initially invalid (caller must 93 | // call one of the seek methods on the iterator before using it). 94 | // 95 | // Caller should delete the iterator when it is no longer needed. 96 | // The returned iterator should be closed before this db is closed. 97 | newIterator(): LevelDBIteratorI; 98 | } 99 | 100 | export class LevelDBIterator implements LevelDBIteratorI { 101 | private ref: number; 102 | 103 | constructor(dbRef: number) { 104 | this.ref = g.leveldbNewIterator(dbRef); 105 | } 106 | 107 | seekToFirst(): LevelDBIterator { 108 | g.leveldbIteratorSeekToFirst(this.ref); 109 | return this; 110 | } 111 | 112 | seekLast(): LevelDBIterator { 113 | g.leveldbIteratorSeekToLast(this.ref); 114 | return this; 115 | } 116 | 117 | seek(target: ArrayBuffer | string): LevelDBIterator { 118 | g.leveldbIteratorSeek(this.ref, target); 119 | return this; 120 | } 121 | 122 | valid(): boolean { 123 | return g.leveldbIteratorValid(this.ref); 124 | } 125 | 126 | next(): void { 127 | g.leveldbIteratorNext(this.ref); 128 | } 129 | 130 | prev(): void { 131 | g.leveldbIteratorPrev(this.ref); 132 | } 133 | 134 | close() { 135 | g.leveldbIteratorDelete(this.ref); 136 | this.ref = -1; 137 | } 138 | 139 | keyStr(): string { 140 | return g.leveldbIteratorKeyStr(this.ref); 141 | } 142 | 143 | keyBuf(): ArrayBuffer { 144 | return g.leveldbIteratorKeyBuf(this.ref); 145 | } 146 | 147 | valueStr(): string { 148 | return g.leveldbIteratorValueStr(this.ref); 149 | } 150 | 151 | valueBuf(): ArrayBuffer { 152 | return g.leveldbIteratorValueBuf(this.ref); 153 | } 154 | compareKey(target: ArrayBuffer | string) : number { 155 | return g.leveldbIteratorKeyCompare(this.ref, target); 156 | } 157 | } 158 | 159 | export class LevelDB implements LevelDBI { 160 | // Keep references to already open DBs here to facilitate RN's edit-refresh flow. 161 | // Note that when editing this file, this won't work, as RN will reload it and the openPathRefs 162 | // will be lost. 163 | private static openPathRefs: { [name: string]: undefined | number } = {}; 164 | private ref: undefined | number; 165 | 166 | constructor(name: string, createIfMissing: boolean, errorIfExists: boolean) { 167 | if (nativeModuleInitError) { 168 | throw new Error(nativeModuleInitError); 169 | } 170 | 171 | if (LevelDB.openPathRefs[name] !== undefined) { 172 | this.ref = LevelDB.openPathRefs[name]; 173 | } else { 174 | LevelDB.openPathRefs[name] = this.ref = g.leveldbOpen(name, createIfMissing, errorIfExists); 175 | } 176 | } 177 | 178 | close() { 179 | g.leveldbClose(this.ref); 180 | for (const name in LevelDB.openPathRefs) { 181 | if (LevelDB.openPathRefs[name] === this.ref) { 182 | delete LevelDB.openPathRefs[name]; 183 | } 184 | } 185 | this.ref = undefined; 186 | } 187 | 188 | closed(): boolean { 189 | return this.ref === undefined || !Object.values(LevelDB.openPathRefs).includes(this.ref); 190 | } 191 | 192 | put(k: ArrayBuffer | string, v: ArrayBuffer | string) { 193 | g.leveldbPut(this.ref, k, v); 194 | } 195 | 196 | delete(k: ArrayBuffer | string) { 197 | g.leveldbDelete(this.ref, k); 198 | } 199 | 200 | getStr(k: ArrayBuffer | string): null | string { 201 | return g.leveldbGetStr(this.ref, k); 202 | } 203 | 204 | getBuf(k: ArrayBuffer | string): null | ArrayBuffer { 205 | return g.leveldbGetBuf(this.ref, k); 206 | } 207 | 208 | newIterator(): LevelDBIterator { 209 | if (this.ref === undefined) { 210 | throw new Error('LevelDB.newIterator: could not create iterator, the DB was closed!'); 211 | } 212 | return new LevelDBIterator(this.ref); 213 | } 214 | 215 | // Merges the data from another LevelDB into this one. All keys from src will be written into this LevelDB, 216 | // overwriting any existing values. 217 | // batchMerge=true will write all values from src in one transaction, thus ensuring that the dst DB is not left 218 | // in a corrupt state. 219 | merge(src: LevelDB, batchMerge: boolean) { 220 | if (this.ref === undefined) { 221 | throw new Error('LevelDB.merge: could not merge, the dest DB (this) was closed!'); 222 | } 223 | if (src.ref === undefined) { 224 | throw new Error('LevelDB.merge: could not merge, the source DB was closed!'); 225 | } 226 | g.leveldbMerge(this.ref, src.ref, batchMerge); 227 | } 228 | 229 | static destroyDB(name: string, force?: boolean) { 230 | if (LevelDB.openPathRefs[name] !== undefined) { 231 | if (force) { 232 | g.leveldbClose(LevelDB.openPathRefs[name]); 233 | delete LevelDB.openPathRefs[name]; 234 | } else { 235 | throw new Error('DB is open! Cannot destroy'); 236 | } 237 | } 238 | 239 | g.leveldbDestroy(name); 240 | } 241 | 242 | static readFileToBuf = g.leveldbReadFileBuf as (path: string, pos: number, len: number) => ArrayBuffer; 243 | } 244 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "extends": "./tsconfig", 4 | "exclude": ["example"] 5 | } 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "react-native-leveldb": ["./src/index"] 6 | }, 7 | "allowUnreachableCode": false, 8 | "allowUnusedLabels": false, 9 | "esModuleInterop": true, 10 | "importsNotUsedAsValues": "error", 11 | "forceConsistentCasingInFileNames": true, 12 | "jsx": "react", 13 | "lib": ["esnext"], 14 | "module": "esnext", 15 | "moduleResolution": "node", 16 | "noFallthroughCasesInSwitch": true, 17 | "noImplicitReturns": true, 18 | "noImplicitUseStrict": false, 19 | "noStrictGenericChecks": false, 20 | "noUncheckedIndexedAccess": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "resolveJsonModule": true, 24 | "skipLibCheck": true, 25 | "strict": true, 26 | "target": "esnext" 27 | } 28 | } 29 | --------------------------------------------------------------------------------