react-native-fast-json 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FastJson.podspec +41 -0
- package/LICENSE +20 -0
- package/README.md +162 -0
- package/android/CMakeLists.txt +37 -0
- package/android/build.gradle +119 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/cpp-adapter.cpp +11 -0
- package/android/src/main/java/com/margelo/nitro/fastjson/FastJsonPackage.kt +22 -0
- package/cpp/HybridFastJson.cpp +61 -0
- package/cpp/HybridFastJson.hpp +19 -0
- package/cpp/HybridJsonView.cpp +370 -0
- package/cpp/HybridJsonView.hpp +39 -0
- package/cpp/third_party/simdjson.cpp +65338 -0
- package/cpp/third_party/simdjson.h +186793 -0
- package/lib/module/FastJson.nitro.js +4 -0
- package/lib/module/FastJson.nitro.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/FastJson.nitro.d.ts +85 -0
- package/lib/typescript/src/FastJson.nitro.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/nitro.json +19 -0
- package/nitrogen/generated/android/fastjson+autolinking.cmake +82 -0
- package/nitrogen/generated/android/fastjson+autolinking.gradle +27 -0
- package/nitrogen/generated/android/fastjsonOnLoad.cpp +49 -0
- package/nitrogen/generated/android/fastjsonOnLoad.hpp +34 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/fastjson/fastjsonOnLoad.kt +35 -0
- package/nitrogen/generated/ios/FastJson+autolinking.rb +62 -0
- package/nitrogen/generated/ios/FastJson-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/FastJson-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/FastJson-Swift-Cxx-Umbrella.hpp +38 -0
- package/nitrogen/generated/ios/FastJsonAutolinking.mm +35 -0
- package/nitrogen/generated/ios/FastJsonAutolinking.swift +16 -0
- package/nitrogen/generated/shared/c++/HybridFastJsonSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridFastJsonSpec.hpp +70 -0
- package/nitrogen/generated/shared/c++/HybridJsonViewSpec.cpp +34 -0
- package/nitrogen/generated/shared/c++/HybridJsonViewSpec.hpp +81 -0
- package/package.json +185 -0
- package/src/FastJson.nitro.ts +86 -0
- package/src/index.tsx +6 -0
package/FastJson.podspec
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
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 = "FastJson"
|
|
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
|
+
# Align with Swift CxxStdlib / Nitro toolchains (iOS 16+).
|
|
14
|
+
s.platforms = { :ios => '16.0' }
|
|
15
|
+
s.source = { :git => "https://github.com/ifeoluwak/react-native-fast-json.git", :tag => "#{s.version}" }
|
|
16
|
+
|
|
17
|
+
s.source_files = [
|
|
18
|
+
"ios/**/*.{swift}",
|
|
19
|
+
"ios/**/*.{m,mm}",
|
|
20
|
+
# .h: simdjson amalgamation header in cpp/third_party
|
|
21
|
+
"cpp/**/*.{h,hpp,cpp}",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Force O3 optimization specifically for C++ files
|
|
26
|
+
s.compiler_flags = '-O3 -DNDEBUG'
|
|
27
|
+
|
|
28
|
+
s.pod_target_xcconfig = {
|
|
29
|
+
'GCC_OPTIMIZATION_LEVEL' => '3',
|
|
30
|
+
'OTHER_CPLUSPLUSFLAGS' => '-O3 -DNDEBUG',
|
|
31
|
+
"HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/cpp\" \"$(PODS_TARGET_SRCROOT)/cpp/third_party\" $(inherited)",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
s.dependency 'React-jsi'
|
|
35
|
+
s.dependency 'React-callinvoker'
|
|
36
|
+
|
|
37
|
+
load 'nitrogen/generated/ios/FastJson+autolinking.rb'
|
|
38
|
+
add_nitrogen_files(s)
|
|
39
|
+
|
|
40
|
+
install_modules_dependencies(s)
|
|
41
|
+
end
|
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ifeoluwa
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# react-native-fast-json
|
|
2
|
+
|
|
3
|
+
**`JSON.parse`** turns the whole file into nested JavaScript objects in the same memory as your app code. That is fine for small JSON; for **very large files** (on the order of **tens to hundreds of MB**), it often means:
|
|
4
|
+
|
|
5
|
+
- CPU stays pegged high while parsing finishes
|
|
6
|
+
- The screen **freezes or stutters**
|
|
7
|
+
- Memory use jumps; in bad cases the app is **killed for using too much memory**
|
|
8
|
+
|
|
9
|
+
**This library** parses in **native** code with [simdjson](https://github.com/simdjson/simdjson) and exposes a **`JsonView`** through [Nitro Modules](https://nitro.margelo.com/)—you read the document **lazily** from native memory instead of inflating everything into one giant JavaScript tree up front.
|
|
10
|
+
|
|
11
|
+
**Rough illustration** for a **~250 MB** file (device and JSON shape will change this):
|
|
12
|
+
|
|
13
|
+
| | `JSON.parse` | `parseFile` + root `JsonView` |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| **Parse / load** | Often **many seconds** on a phone (every object is allocated in JS) | Native read + parse often **~100 ms** for the same **~250 MB**—**near-instant** at UI scale; exact time depends on disk and CPU |
|
|
16
|
+
| **CPU** | Long spikes (often **>100%** in system monitors) | **Calmer** during native load/parse |
|
|
17
|
+
| **Memory (ballpark)** | **~1.2 GB** in a heavy case | **~400 MB** (the file still has to live somewhere) |
|
|
18
|
+
|
|
19
|
+
These numbers are **illustrative only**—measure your own file on real hardware before you budget.
|
|
20
|
+
|
|
21
|
+
## When to use it
|
|
22
|
+
|
|
23
|
+
- Large JSON (for example **~100–200 MB+**: catalogs, offline bundles, big dumps) where **`JSON.parse`** feels too slow, freezes the UI, or uses too much memory.
|
|
24
|
+
- Mostly **read-only**, **targeted** access: a few keys, paths, or scalars.
|
|
25
|
+
|
|
26
|
+
Prefer normal **`JSON.parse`** for small responses and whenever you need the full tree as plain JS objects anyway.
|
|
27
|
+
|
|
28
|
+
## Requirements
|
|
29
|
+
|
|
30
|
+
- React Native with the setup expected by Nitro (see [Nitro docs](https://nitro.margelo.com/)).
|
|
31
|
+
- **`react-native-nitro-modules`** as a dependency (peer).
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
yarn add react-native-fast-json react-native-nitro-modules
|
|
37
|
+
# or
|
|
38
|
+
npm install react-native-fast-json react-native-nitro-modules
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Then install iOS pods from your app root:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
cd ios && pod install
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Rebuild the native app after adding the dependency.
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { fastJson, type JsonView } from 'react-native-fast-json';
|
|
53
|
+
|
|
54
|
+
// From a JSON string (loads into native memory; not cached by path)
|
|
55
|
+
const root = await fastJson.parseString(jsonString);
|
|
56
|
+
if (!root) return;
|
|
57
|
+
|
|
58
|
+
//Preferred - From a file path (native reads the file; result is cached per path)
|
|
59
|
+
const fromFile = await fastJson.parseFile('/path/to/data.json');
|
|
60
|
+
|
|
61
|
+
// Drop cached parse for that path when you are done (see Memory below)
|
|
62
|
+
fastJson.release('/path/to/data.json');
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### `JsonView`
|
|
66
|
+
|
|
67
|
+
Navigate and read values without building a full JS tree up front:
|
|
68
|
+
|
|
69
|
+
| Method / property | Purpose |
|
|
70
|
+
|-------------------|--------|
|
|
71
|
+
| `getValue(key)` | Single object key (not a path). Returns `JsonView \| null`. |
|
|
72
|
+
| `keys()` | Keys for objects / arrays (as applicable). |
|
|
73
|
+
| `at(index)` | Array element by index. |
|
|
74
|
+
| `atPath('$.a.b.c')` | Simple dotted path from `$` (no `[index]` in path). |
|
|
75
|
+
| `atPathWithWildcard('$.items[*].id')` | Wildcard / index segments; returns `string[] \| null`. |
|
|
76
|
+
| `type`, `length` | Value kind and length (objects/arrays). |
|
|
77
|
+
| `asString()`, `asNumber()`, `asBoolean()` | Scalar coercion. |
|
|
78
|
+
| `asObject()` | Materialize object/array into an `AnyMap` (expensive for large values). |
|
|
79
|
+
| `rawJson()` | Raw JSON slice as string (can be expensive for large values). |
|
|
80
|
+
|
|
81
|
+
Example:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
const meta = root.getValue('metadata');
|
|
85
|
+
const version = meta?.getValue('version')?.asString();
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Memory and caching
|
|
89
|
+
|
|
90
|
+
### How big is “big”?
|
|
91
|
+
|
|
92
|
+
Native memory for a parse is dominated by the **root buffer**, which is roughly **the JSON byte size plus simdjson padding** (think **on the order of the file size**, not “a few MB overhead”).
|
|
93
|
+
|
|
94
|
+
| Rough file size | What to expect |
|
|
95
|
+
|-----------------|------------------|
|
|
96
|
+
| **Under ~10 MB** | Usually fine to keep a root around for a screen session if you need repeated lazy access. |
|
|
97
|
+
| **~10–50 MB** | Still workable; treat the root as a **large native allocation** and avoid keeping multiple overlapping parses. |
|
|
98
|
+
| **~50–200 MB** | High impact on device RAM and OOM risk if you stack parses or retain roots in global state. Plan **`release(path)`** and avoid `rawJson` / `asObject` on the whole document. |
|
|
99
|
+
| **200 MB+** | Same as above, but stricter: **short-lived root**, extract what you need, then drop handles immediately (see below). |
|
|
100
|
+
|
|
101
|
+
These are ballparks—actual pressure depends on device, OS, and what else your app keeps in JavaScript memory versus native (C++) memory.
|
|
102
|
+
|
|
103
|
+
### Prefer a short-lived root: read what you need, then discard
|
|
104
|
+
|
|
105
|
+
**Do not** keep the root `JsonView` in React state, context, or a singleton for the whole app lifetime unless you truly need random access to that document for a long time.
|
|
106
|
+
|
|
107
|
+
A safer pattern for large files:
|
|
108
|
+
|
|
109
|
+
1. **`parseFile`** (or `parseString`) once when you need the data.
|
|
110
|
+
2. In the **same synchronous stretch** (or one small async function), walk the tree and **copy** primitives, small objects, or IDs into **plain JavaScript** values you actually store in state.
|
|
111
|
+
3. **Clear** your `JsonView` references and call **`release(path)`** for file parses so the native cache and buffer can go away.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
async function loadConfig(path: string) {
|
|
115
|
+
const root = await fastJson.parseFile(path);
|
|
116
|
+
try {
|
|
117
|
+
const version = root?.getValue('metadata')?.getValue('version')?.asString();
|
|
118
|
+
const batchSize = root
|
|
119
|
+
?.atPath('$.metadata.configuration.export_settings.batch_size')
|
|
120
|
+
?.asNumber();
|
|
121
|
+
return { version, batchSize }; // plain JS — safe to keep
|
|
122
|
+
} finally {
|
|
123
|
+
fastJson.release(path);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
That way you pay the large native buffer only while you extract fields—not for the entire time the user has the app open.
|
|
129
|
+
|
|
130
|
+
If you **do** need the root for a while (e.g. a deep drill-down UI over the same file), keep **one** root per path, avoid overlapping second parses of the same huge file, and still **`release`** when the user leaves the flow.
|
|
131
|
+
|
|
132
|
+
### Other rules of thumb
|
|
133
|
+
|
|
134
|
+
- **Root `JsonView`** holds the **full parsed buffer** in native memory (file size + padding for `parseFile`, string size for `parseString`).
|
|
135
|
+
- **`parseFile(path)`** caches the native view **by path string**. Repeated `parseFile` with the same path returns the same cached root until **`release(path)`** removes it.
|
|
136
|
+
- **`parseString`** does **not** use that path cache; each call allocates a new native view for that string (until the JS side drops the `JsonView`).
|
|
137
|
+
- **`getValue` / `at` / paths** may create **child** views that copy JSON slices into their own buffers. Holding many large subtrees can add up.
|
|
138
|
+
- **`rawJson()`** and **`asObject()`** on very large values can allocate **large** extra memory (strings / maps). Use sparingly on big documents.
|
|
139
|
+
|
|
140
|
+
If you only need a subtree in JavaScript, you can still hold just that subtree—but while **`parseFile`** keeps the root in the path cache, the **full file buffer** stays in native memory until you **`release`** that path (and nothing else retains the view).
|
|
141
|
+
|
|
142
|
+
## API summary
|
|
143
|
+
|
|
144
|
+
| Method | Description |
|
|
145
|
+
|--------|-------------|
|
|
146
|
+
| `parseString(str)` | Parse JSON from a string. |
|
|
147
|
+
| `parseFile(path)` | Load and parse JSON from a filesystem path; cached by `path`. |
|
|
148
|
+
| `release(path)` | Remove cached parse for `path` (file cache only). |
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
- [Development workflow](CONTRIBUTING.md#development-workflow)
|
|
153
|
+
- [Sending a pull request](CONTRIBUTING.md#sending-a-pull-request)
|
|
154
|
+
- [Code of conduct](CODE_OF_CONDUCT.md)
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
MIT
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
project(fastjson)
|
|
2
|
+
cmake_minimum_required(VERSION 3.9.0)
|
|
3
|
+
|
|
4
|
+
set(PACKAGE_NAME fastjson)
|
|
5
|
+
set(CMAKE_VERBOSE_MAKEFILE ON)
|
|
6
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
7
|
+
|
|
8
|
+
# Define C++ library and add all sources
|
|
9
|
+
add_library(
|
|
10
|
+
${PACKAGE_NAME}
|
|
11
|
+
SHARED
|
|
12
|
+
src/main/cpp/cpp-adapter.cpp
|
|
13
|
+
../cpp/third_party/simdjson.cpp
|
|
14
|
+
../cpp/HybridJsonView.cpp
|
|
15
|
+
../cpp/HybridFastJson.cpp
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# Add Nitrogen specs :)
|
|
19
|
+
include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/fastjson+autolinking.cmake)
|
|
20
|
+
|
|
21
|
+
# simdjson amalgamation + project C++
|
|
22
|
+
target_include_directories(
|
|
23
|
+
${PACKAGE_NAME}
|
|
24
|
+
PRIVATE
|
|
25
|
+
src/main/cpp
|
|
26
|
+
../cpp
|
|
27
|
+
../cpp/third_party
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
find_library(LOG_LIB log)
|
|
31
|
+
|
|
32
|
+
# Link all libraries together
|
|
33
|
+
target_link_libraries(
|
|
34
|
+
${PACKAGE_NAME}
|
|
35
|
+
${LOG_LIB}
|
|
36
|
+
android # <-- Android core
|
|
37
|
+
)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
ext.FastJson = [
|
|
3
|
+
kotlinVersion: "2.0.21",
|
|
4
|
+
minSdkVersion: 24,
|
|
5
|
+
compileSdkVersion: 36,
|
|
6
|
+
targetSdkVersion: 36
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
ext.getExtOrDefault = { prop ->
|
|
10
|
+
if (rootProject.ext.has(prop)) {
|
|
11
|
+
return rootProject.ext.get(prop)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return FastJson[prop]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
repositories {
|
|
18
|
+
google()
|
|
19
|
+
mavenCentral()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
dependencies {
|
|
23
|
+
classpath "com.android.tools.build:gradle:8.7.2"
|
|
24
|
+
// noinspection DifferentKotlinGradleVersion
|
|
25
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
def reactNativeArchitectures() {
|
|
30
|
+
def value = rootProject.getProperties().get("reactNativeArchitectures")
|
|
31
|
+
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
apply plugin: "com.android.library"
|
|
35
|
+
apply plugin: "kotlin-android"
|
|
36
|
+
apply from: '../nitrogen/generated/android/fastjson+autolinking.gradle'
|
|
37
|
+
|
|
38
|
+
apply plugin: "com.facebook.react"
|
|
39
|
+
|
|
40
|
+
android {
|
|
41
|
+
namespace "com.margelo.nitro.fastjson"
|
|
42
|
+
|
|
43
|
+
compileSdkVersion getExtOrDefault("compileSdkVersion")
|
|
44
|
+
|
|
45
|
+
defaultConfig {
|
|
46
|
+
minSdkVersion getExtOrDefault("minSdkVersion")
|
|
47
|
+
targetSdkVersion getExtOrDefault("targetSdkVersion")
|
|
48
|
+
|
|
49
|
+
externalNativeBuild {
|
|
50
|
+
cmake {
|
|
51
|
+
cppFlags "-frtti -fexceptions -Wall -fstack-protector-all"
|
|
52
|
+
arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
|
|
53
|
+
abiFilters (*reactNativeArchitectures())
|
|
54
|
+
|
|
55
|
+
// Match iOS FastJson.podspec: fast simdjson in Debug app builds too (consumers debug JS, not this native code).
|
|
56
|
+
buildTypes {
|
|
57
|
+
debug {
|
|
58
|
+
cppFlags "-O3 -DNDEBUG"
|
|
59
|
+
}
|
|
60
|
+
release {
|
|
61
|
+
cppFlags "-O3 -DNDEBUG"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
externalNativeBuild {
|
|
69
|
+
cmake {
|
|
70
|
+
path "CMakeLists.txt"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
packagingOptions {
|
|
75
|
+
excludes = [
|
|
76
|
+
"META-INF",
|
|
77
|
+
"META-INF/**",
|
|
78
|
+
"**/libc++_shared.so",
|
|
79
|
+
"**/libfbjni.so",
|
|
80
|
+
"**/libjsi.so",
|
|
81
|
+
"**/libfolly_json.so",
|
|
82
|
+
"**/libfolly_runtime.so",
|
|
83
|
+
"**/libglog.so",
|
|
84
|
+
"**/libhermes.so",
|
|
85
|
+
"**/libhermes-executor-debug.so",
|
|
86
|
+
"**/libhermes_executor.so",
|
|
87
|
+
"**/libreactnative.so",
|
|
88
|
+
"**/libreactnativejni.so",
|
|
89
|
+
"**/libturbomodulejsijni.so",
|
|
90
|
+
"**/libreact_nativemodule_core.so",
|
|
91
|
+
"**/libjscexecutor.so"
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
buildFeatures {
|
|
96
|
+
buildConfig true
|
|
97
|
+
prefab true
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
buildTypes {
|
|
101
|
+
release {
|
|
102
|
+
minifyEnabled false
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
lint {
|
|
107
|
+
disable "GradleCompatible"
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
compileOptions {
|
|
111
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
112
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
dependencies {
|
|
117
|
+
implementation "com.facebook.react:react-android"
|
|
118
|
+
implementation project(":react-native-nitro-modules")
|
|
119
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package com.margelo.nitro.fastjson
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
7
|
+
|
|
8
|
+
class FastJsonPackage : BaseReactPackage() {
|
|
9
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
10
|
+
return null
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
|
|
14
|
+
return ReactModuleInfoProvider { HashMap() }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
companion object {
|
|
18
|
+
init {
|
|
19
|
+
System.loadLibrary("fastjson")
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#include "HybridFastJson.hpp"
|
|
2
|
+
|
|
3
|
+
#include <NitroModules/Promise.hpp>
|
|
4
|
+
#include "HybridJsonView.hpp"
|
|
5
|
+
|
|
6
|
+
#include <simdjson.h>
|
|
7
|
+
|
|
8
|
+
namespace margelo::nitro::fastjson
|
|
9
|
+
{
|
|
10
|
+
|
|
11
|
+
std::unordered_map<std::string, std::shared_ptr<HybridJsonViewSpec>> jsonStrings;
|
|
12
|
+
|
|
13
|
+
HybridFastJson::HybridFastJson() : HybridObject(TAG) {}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Parses a JSON string and returns a Promise that resolves to a JsonViewSpec.
|
|
17
|
+
* Not ideal, prefer parseFile or use simple JSON.parse if possible.
|
|
18
|
+
* @param str The JSON string.
|
|
19
|
+
* @returns A Promise that resolves to a JsonViewSpec or null. Not cached (unlike parseFile).
|
|
20
|
+
*/
|
|
21
|
+
std::shared_ptr<Promise<ParseResult>> HybridFastJson::parseString(const std::string &str)
|
|
22
|
+
{
|
|
23
|
+
std::shared_ptr<HybridJsonView> view = std::make_shared<HybridJsonView>();
|
|
24
|
+
view->pstr = str;
|
|
25
|
+
|
|
26
|
+
std::shared_ptr<HybridJsonViewSpec> asSpec = view;
|
|
27
|
+
|
|
28
|
+
return Promise<ParseResult>::resolved(ParseResult{std::move(asSpec)});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parses a JSON file and returns a Promise that resolves to a JsonViewSpec.
|
|
34
|
+
* No check is done if invalid path is provided. Error handling is left to the caller.
|
|
35
|
+
* @param path The path to the JSON file.
|
|
36
|
+
* @returns A Promise that resolves to a JsonViewSpec or null. Response is cached for future calls.
|
|
37
|
+
*/
|
|
38
|
+
std::shared_ptr<Promise<ParseResult>> HybridFastJson::parseFile(const std::string& path)
|
|
39
|
+
{
|
|
40
|
+
if (jsonStrings.find(path) != jsonStrings.end())
|
|
41
|
+
{
|
|
42
|
+
return Promise<ParseResult>::resolved(ParseResult{jsonStrings[path]});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
std::shared_ptr<HybridJsonView> view = std::make_shared<HybridJsonView>();
|
|
46
|
+
view->pstr = simdjson::padded_string::load(path);
|
|
47
|
+
|
|
48
|
+
std::shared_ptr<HybridJsonViewSpec> asSpec = view;
|
|
49
|
+
|
|
50
|
+
jsonStrings[path] = asSpec;
|
|
51
|
+
|
|
52
|
+
return Promise<ParseResult>::resolved(ParseResult{asSpec});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
void HybridFastJson::release(const std::string &source)
|
|
57
|
+
{
|
|
58
|
+
jsonStrings.erase(source);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
} // namespace margelo::nitro::fastjson
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "HybridFastJsonSpec.hpp"
|
|
4
|
+
#include "HybridJsonViewSpec.hpp"
|
|
5
|
+
|
|
6
|
+
namespace margelo::nitro::fastjson {
|
|
7
|
+
|
|
8
|
+
using ParseResult = std::variant<nitro::NullType, std::shared_ptr<HybridJsonViewSpec>>;
|
|
9
|
+
|
|
10
|
+
class HybridFastJson : public HybridFastJsonSpec {
|
|
11
|
+
public:
|
|
12
|
+
HybridFastJson();
|
|
13
|
+
|
|
14
|
+
std::shared_ptr<Promise<std::variant<nitro::NullType, std::shared_ptr<HybridJsonViewSpec>>>> parseString(const std::string& str) override;
|
|
15
|
+
std::shared_ptr<Promise<std::variant<nitro::NullType, std::shared_ptr<HybridJsonViewSpec>>>> parseFile(const std::string& path) override;
|
|
16
|
+
void release(const std::string& source) override;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
} // namespace margelo::nitro::fastjson
|