mindoodb 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -19
- package/dist/__mocks__/expo-standard-web-crypto.d.ts +10 -0
- package/dist/__mocks__/expo-standard-web-crypto.d.ts.map +1 -0
- package/dist/__mocks__/expo-standard-web-crypto.js +22 -0
- package/dist/__mocks__/expo-standard-web-crypto.js.map +1 -0
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts +8 -0
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts.map +1 -0
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js +16 -0
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js.map +1 -0
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts +1 -1
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts.map +1 -1
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js +2 -2
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js.map +1 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +11 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +94 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
- package/dist/appendonlystores/network/HttpTransport.d.ts +13 -2
- package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
- package/dist/appendonlystores/network/HttpTransport.js +86 -0
- package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +19 -2
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +96 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -1
- package/dist/appendonlystores/network/index.d.ts +1 -1
- package/dist/appendonlystores/network/index.d.ts.map +1 -1
- package/dist/appendonlystores/network/index.js.map +1 -1
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts +61 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts.map +1 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js +685 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js.map +1 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.d.ts +25 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.d.ts.map +1 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.js +41 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.js.map +1 -0
- package/dist/browser/index.d.ts +5 -0
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +13 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/core/BaseMindooDB.d.ts +12 -0
- package/dist/core/BaseMindooDB.d.ts.map +1 -1
- package/dist/core/BaseMindooDB.js +210 -108
- package/dist/core/BaseMindooDB.js.map +1 -1
- package/dist/core/BaseMindooTenant.d.ts +40 -6
- package/dist/core/BaseMindooTenant.d.ts.map +1 -1
- package/dist/core/BaseMindooTenant.js +179 -21
- package/dist/core/BaseMindooTenant.js.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.js +10 -0
- package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
- package/dist/core/BaseMindooTenantFactory.d.ts +22 -28
- package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantFactory.js +161 -65
- package/dist/core/BaseMindooTenantFactory.js.map +1 -1
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +68 -0
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -0
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js +659 -0
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +43 -3
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -1
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +162 -23
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -1
- package/dist/core/appendonlystores/bloom.d.ts +85 -0
- package/dist/core/appendonlystores/bloom.d.ts.map +1 -0
- package/dist/core/appendonlystores/bloom.js +228 -0
- package/dist/core/appendonlystores/bloom.js.map +1 -0
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts +22 -2
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/types.d.ts +10 -0
- package/dist/core/appendonlystores/network/types.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/types.js.map +1 -1
- package/dist/core/appendonlystores/types.d.ts +123 -0
- package/dist/core/appendonlystores/types.d.ts.map +1 -1
- package/dist/core/automerge-adapter.d.ts +15 -0
- package/dist/core/automerge-adapter.d.ts.map +1 -0
- package/dist/core/automerge-adapter.js +73 -0
- package/dist/core/automerge-adapter.js.map +1 -0
- package/dist/core/crypto/pbkdf2Iterations.d.ts +12 -0
- package/dist/core/crypto/pbkdf2Iterations.d.ts.map +1 -0
- package/dist/core/crypto/pbkdf2Iterations.js +55 -0
- package/dist/core/crypto/pbkdf2Iterations.js.map +1 -0
- package/dist/core/index.d.ts +7 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +30 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/keys/KeyBag.d.ts +32 -12
- package/dist/core/keys/KeyBag.d.ts.map +1 -1
- package/dist/core/keys/KeyBag.js +86 -26
- package/dist/core/keys/KeyBag.js.map +1 -1
- package/dist/core/keys/KeyContext.d.ts +4 -0
- package/dist/core/keys/KeyContext.d.ts.map +1 -0
- package/dist/core/keys/KeyContext.js +11 -0
- package/dist/core/keys/KeyContext.js.map +1 -0
- package/dist/core/types.d.ts +218 -50
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/uri/MindooURI.d.ts +58 -0
- package/dist/core/uri/MindooURI.d.ts.map +1 -0
- package/dist/core/uri/MindooURI.js +169 -0
- package/dist/core/uri/MindooURI.js.map +1 -0
- package/dist/core/userid/index.d.ts +0 -10
- package/dist/core/userid/index.d.ts.map +1 -1
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +541 -0
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -0
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +1334 -0
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -0
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +5 -1
- package/dist/node/index.js.map +1 -1
- package/dist/reactnative/crypto/AESAdapter.d.ts +18 -0
- package/dist/reactnative/crypto/AESAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/AESAdapter.js +112 -0
- package/dist/reactnative/crypto/AESAdapter.js.map +1 -0
- package/dist/reactnative/crypto/Ed25519Adapter.d.ts +34 -0
- package/dist/reactnative/crypto/Ed25519Adapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/Ed25519Adapter.js +386 -0
- package/dist/reactnative/crypto/Ed25519Adapter.js.map +1 -0
- package/dist/reactnative/crypto/ExpoGoCryptoAdapter.d.ts +23 -0
- package/dist/reactnative/crypto/ExpoGoCryptoAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/ExpoGoCryptoAdapter.js +51 -0
- package/dist/reactnative/crypto/ExpoGoCryptoAdapter.js.map +1 -0
- package/dist/reactnative/crypto/HMACAdapter.d.ts +13 -0
- package/dist/reactnative/crypto/HMACAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/HMACAdapter.js +50 -0
- package/dist/reactnative/crypto/HMACAdapter.js.map +1 -0
- package/dist/reactnative/crypto/KeyFormatConverter.d.ts +21 -0
- package/dist/reactnative/crypto/KeyFormatConverter.d.ts.map +1 -0
- package/dist/reactnative/crypto/KeyFormatConverter.js +72 -0
- package/dist/reactnative/crypto/KeyFormatConverter.js.map +1 -0
- package/dist/reactnative/crypto/PBKDF2Adapter.d.ts +19 -0
- package/dist/reactnative/crypto/PBKDF2Adapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/PBKDF2Adapter.js +67 -0
- package/dist/reactnative/crypto/PBKDF2Adapter.js.map +1 -0
- package/dist/reactnative/crypto/QuickCryptoAdapter.d.ts +37 -0
- package/dist/reactnative/crypto/QuickCryptoAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/QuickCryptoAdapter.js +72 -0
- package/dist/reactnative/crypto/QuickCryptoAdapter.js.map +1 -0
- package/dist/reactnative/crypto/RSAAdapter.d.ts +38 -0
- package/dist/reactnative/crypto/RSAAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/RSAAdapter.js +184 -0
- package/dist/reactnative/crypto/RSAAdapter.js.map +1 -0
- package/dist/reactnative/crypto/ReactNativeCryptoAdapter.d.ts +33 -0
- package/dist/reactnative/crypto/ReactNativeCryptoAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/ReactNativeCryptoAdapter.js +61 -0
- package/dist/reactnative/crypto/ReactNativeCryptoAdapter.js.map +1 -0
- package/dist/reactnative/crypto/SHA256Adapter.d.ts +9 -0
- package/dist/reactnative/crypto/SHA256Adapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/SHA256Adapter.js +29 -0
- package/dist/reactnative/crypto/SHA256Adapter.js.map +1 -0
- package/dist/reactnative/crypto/SubtleCryptoPolyfill.d.ts +63 -0
- package/dist/reactnative/crypto/SubtleCryptoPolyfill.d.ts.map +1 -0
- package/dist/reactnative/crypto/SubtleCryptoPolyfill.js +350 -0
- package/dist/reactnative/crypto/SubtleCryptoPolyfill.js.map +1 -0
- package/dist/reactnative/index.d.ts +8 -0
- package/dist/reactnative/index.d.ts.map +1 -0
- package/dist/reactnative/index.js +38 -0
- package/dist/reactnative/index.js.map +1 -0
- package/package.json +51 -6
- package/patches/PATCHES.md +111 -0
- package/patches/react-native+0.76.9.patch +34 -0
- package/patches/react-native-quick-crypto+1.0.7.patch +42 -0
- package/scripts/cli.js +21 -0
- package/scripts/setup-react-native.js +228 -0
- package/templates/reactnative/App.js +252 -0
- package/templates/reactnative/app.json +29 -0
- package/templates/reactnative/babel.config.js +6 -0
- package/templates/reactnative/index.js +26 -0
- package/templates/reactnative/metro.config.snippet.js +39 -0
- package/templates/reactnative/mindoodb-polyfills.js +116 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Patches
|
|
2
|
+
|
|
3
|
+
This project uses [patch-package](https://github.com/ds300/patch-package) to fix bugs in dependencies. Patches are applied automatically on `npm install` via the `postinstall` script.
|
|
4
|
+
|
|
5
|
+
All patches target the specific dependency versions listed below. After upgrading a patched dependency, verify whether the upstream fix has been merged and remove the patch if so.
|
|
6
|
+
|
|
7
|
+
> **Note:** `react-native-quick-crypto` contains symlinks in its bundled `OpenSSL.xcframework`, which prevents `patch-package` from auto-generating patches. To regenerate that patch, use `git diff` manually against a clean copy of the package (see procedure below).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## react-native+0.76.9.patch
|
|
12
|
+
|
|
13
|
+
**File changed:** `ReactCommon/jsc/JSCRuntime.cpp`
|
|
14
|
+
|
|
15
|
+
### Problem
|
|
16
|
+
|
|
17
|
+
React Native's JSC (JavaScriptCore) runtime has `JSCRuntime::createArrayBuffer()` stubbed as:
|
|
18
|
+
|
|
19
|
+
```cpp
|
|
20
|
+
throw std::logic_error("Not implemented");
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This breaks any NitroModules HybridObject method that returns an `ArrayBuffer` from native to JS (e.g., `Hash.digest()` in react-native-quick-crypto). The error surfaces as:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Hash.digest(...): Not implemented
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Fix
|
|
30
|
+
|
|
31
|
+
Implements `createArrayBuffer()` using the JSC C API function `JSObjectMakeArrayBufferWithBytesNoCopy`. The implementation:
|
|
32
|
+
|
|
33
|
+
1. Moves the `shared_ptr<MutableBuffer>` onto the heap so it outlives the function call.
|
|
34
|
+
2. Creates a JSC ArrayBuffer that points directly to the buffer's data (zero-copy).
|
|
35
|
+
3. Registers a deallocator callback that deletes the shared_ptr when the JS garbage collector collects the ArrayBuffer.
|
|
36
|
+
4. Cleans up the heap allocation on failure before re-throwing.
|
|
37
|
+
|
|
38
|
+
### Upstream status
|
|
39
|
+
|
|
40
|
+
Not yet fixed in react-native 0.76.x. The Hermes engine implements this method; only JSC is missing it.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## react-native-quick-crypto+1.0.7.patch
|
|
45
|
+
|
|
46
|
+
**Files changed:**
|
|
47
|
+
- `cpp/random/HybridRandom.cpp`
|
|
48
|
+
- `src/random.ts`
|
|
49
|
+
|
|
50
|
+
### Problem 1: NULL pointer crash in native randomFillSync (SIGSEGV)
|
|
51
|
+
|
|
52
|
+
After extended runtime (~9 hours), the app crashes with a SIGSEGV in OpenSSL's `RAND_bytes` writing to address `0x0`. The crash originates from `HybridRandom::randomFillSync()` at line 42.
|
|
53
|
+
|
|
54
|
+
**Root cause:** `buffer.get()->data()` can return `nullptr` when the JS ArrayBuffer reference has been invalidated. NitroModules' `JSArrayBuffer::data()` is explicitly marked `NULLABLE` and returns `nullptr` when:
|
|
55
|
+
- The JS garbage collector has collected the underlying ArrayBuffer
|
|
56
|
+
- WASM memory growth has detached the ArrayBuffer
|
|
57
|
+
- The `BorrowingReference` to the JS object is no longer valid
|
|
58
|
+
|
|
59
|
+
The native code had **no null check** before passing the pointer to `RAND_bytes()`.
|
|
60
|
+
|
|
61
|
+
**Fix (HybridRandom.cpp):** Added a null check on the data pointer before calling `RAND_bytes`. If null, throws a descriptive `std::runtime_error` that surfaces as a catchable JS exception instead of a fatal SIGSEGV.
|
|
62
|
+
|
|
63
|
+
### Problem 2: WASM memory corruption from TypedArray view handling
|
|
64
|
+
|
|
65
|
+
The original `randomFillSync` TypeScript implementation calls `abvToArrayBuffer(buffer)` which extracts the underlying `.buffer` property from TypedArray views. This **discards the view's `byteOffset` and `byteLength`**, using the full underlying ArrayBuffer's `byteLength` instead.
|
|
66
|
+
|
|
67
|
+
When automerge's WASM module calls `crypto.getRandomValues(wasmMemoryView)`:
|
|
68
|
+
- The TypedArray's `.buffer` is `WebAssembly.Memory.buffer` (the entire WASM linear memory, potentially megabytes)
|
|
69
|
+
- `abvToArrayBuffer()` returns this full buffer
|
|
70
|
+
- `size ?? buffer.byteLength` resolves to the entire WASM memory size
|
|
71
|
+
- The native side writes random bytes to the **entire WASM linear memory**, destroying the heap, stack, and all data
|
|
72
|
+
|
|
73
|
+
This causes automerge to crash with `RuntimeError: Out of bounds memory access` on the next WASM allocation (e.g., `dlmalloc::malloc` during `AutoCommit::new`).
|
|
74
|
+
|
|
75
|
+
> This bug exists in the **unpatched original code** as well, not just our patch. It is masked when WASM rarely calls `getRandomValues`, but is triggered reliably when automerge's Rust code needs random bytes for HashMap seeding.
|
|
76
|
+
|
|
77
|
+
**Fix (random.ts):** Rewrote `randomFillSync` to:
|
|
78
|
+
|
|
79
|
+
1. **Preserve TypedArray view info** before extracting the underlying buffer: reads `buffer.byteOffset` and `buffer.byteLength` from the original TypedArray, so we know exactly which portion of the underlying buffer to fill.
|
|
80
|
+
2. **Create an owned ArrayBuffer** of just the fill size (not the entire underlying buffer). This ensures the native side always receives a valid, correctly-sized buffer that won't be detached by WASM memory growth or GC.
|
|
81
|
+
3. **Copy random bytes back** to the exact correct position in the original buffer using `viewByteOffset + offset`.
|
|
82
|
+
|
|
83
|
+
### Upstream status
|
|
84
|
+
|
|
85
|
+
Neither fix has been submitted upstream to react-native-quick-crypto.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Regenerating the quick-crypto patch
|
|
90
|
+
|
|
91
|
+
Because `patch-package` cannot handle symlinks in `OpenSSL.xcframework`, use this manual procedure:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# 1. Get a clean copy of the package
|
|
95
|
+
npm pack react-native-quick-crypto@1.0.7 --pack-destination /tmp
|
|
96
|
+
mkdir -p /tmp/qc-orig && tar -xzf /tmp/react-native-quick-crypto-1.0.7.tgz -C /tmp/qc-orig
|
|
97
|
+
|
|
98
|
+
# 2. Set up a temp git repo for diffing
|
|
99
|
+
mkdir /tmp/qc-git && cd /tmp/qc-git && git init
|
|
100
|
+
mkdir -p node_modules/react-native-quick-crypto/{cpp/random,src}
|
|
101
|
+
cp /tmp/qc-orig/package/cpp/random/HybridRandom.cpp node_modules/react-native-quick-crypto/cpp/random/
|
|
102
|
+
cp /tmp/qc-orig/package/src/random.ts node_modules/react-native-quick-crypto/src/
|
|
103
|
+
git add . && git commit -m "original"
|
|
104
|
+
|
|
105
|
+
# 3. Copy in your modified files
|
|
106
|
+
cp <project>/node_modules/react-native-quick-crypto/cpp/random/HybridRandom.cpp node_modules/react-native-quick-crypto/cpp/random/
|
|
107
|
+
cp <project>/node_modules/react-native-quick-crypto/src/random.ts node_modules/react-native-quick-crypto/src/
|
|
108
|
+
|
|
109
|
+
# 4. Generate the patch
|
|
110
|
+
git diff --no-color > <project>/patches/react-native-quick-crypto+1.0.7.patch
|
|
111
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
diff --git a/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp b/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp
|
|
2
|
+
index e63260a..b806880 100644
|
|
3
|
+
--- a/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp
|
|
4
|
+
+++ b/node_modules/react-native/ReactCommon/jsc/JSCRuntime.cpp
|
|
5
|
+
@@ -1120,7 +1120,28 @@ jsi::Array JSCRuntime::createArray(size_t length) {
|
|
6
|
+
|
|
7
|
+
jsi::ArrayBuffer JSCRuntime::createArrayBuffer(
|
|
8
|
+
std::shared_ptr<jsi::MutableBuffer> buffer) {
|
|
9
|
+
- throw std::logic_error("Not implemented");
|
|
10
|
+
+ JSValueRef exc = nullptr;
|
|
11
|
+
+ // Move the shared_ptr into heap storage so it survives until JSC deallocates
|
|
12
|
+
+ // the ArrayBuffer. The deallocator callback deletes it when the JS GC
|
|
13
|
+
+ // collects the ArrayBuffer object.
|
|
14
|
+
+ auto* pointerHolder =
|
|
15
|
+
+ new std::shared_ptr<jsi::MutableBuffer>(std::move(buffer));
|
|
16
|
+
+ JSObjectRef obj = JSObjectMakeArrayBufferWithBytesNoCopy(
|
|
17
|
+
+ ctx_,
|
|
18
|
+
+ (*pointerHolder)->data(),
|
|
19
|
+
+ (*pointerHolder)->size(),
|
|
20
|
+
+ [](void* /*bytes*/, void* deallocatorContext) {
|
|
21
|
+
+ delete static_cast<std::shared_ptr<jsi::MutableBuffer>*>(
|
|
22
|
+
+ deallocatorContext);
|
|
23
|
+
+ },
|
|
24
|
+
+ pointerHolder,
|
|
25
|
+
+ &exc);
|
|
26
|
+
+ if (!obj) {
|
|
27
|
+
+ // Clean up on failure before throwing
|
|
28
|
+
+ delete pointerHolder;
|
|
29
|
+
+ checkException(exc);
|
|
30
|
+
+ }
|
|
31
|
+
+ return createObject(obj).getArrayBuffer(*this);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
size_t JSCRuntime::size(const jsi::Array& arr) {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
diff --git a/node_modules/react-native-quick-crypto/cpp/random/HybridRandom.cpp b/node_modules/react-native-quick-crypto/cpp/random/HybridRandom.cpp
|
|
2
|
+
index b1a132c..e48eb06 100644
|
|
3
|
+
--- a/node_modules/react-native-quick-crypto/cpp/random/HybridRandom.cpp
|
|
4
|
+
+++ b/node_modules/react-native-quick-crypto/cpp/random/HybridRandom.cpp
|
|
5
|
+
@@ -39,6 +39,9 @@ std::shared_ptr<ArrayBuffer> HybridRandom::randomFillSync(const std::shared_ptr<
|
|
6
|
+
size_t size = checkSize(dSize);
|
|
7
|
+
size_t offset = checkOffset(dSize, dOffset);
|
|
8
|
+
uint8_t* data = buffer.get()->data();
|
|
9
|
+
+ if (!data) {
|
|
10
|
+
+ throw std::runtime_error("randomFillSync: ArrayBuffer data pointer is null (buffer may have been detached or garbage collected)");
|
|
11
|
+
+ }
|
|
12
|
+
if (RAND_bytes(data + offset, (int)size) != 1) {
|
|
13
|
+
throw std::runtime_error("error calling RAND_bytes: " + std::to_string(ERR_get_error()));
|
|
14
|
+
}
|
|
15
|
+
diff --git a/node_modules/react-native-quick-crypto/src/random.ts b/node_modules/react-native-quick-crypto/src/random.ts
|
|
16
|
+
index 4066c5a..753da81 100644
|
|
17
|
+
--- a/node_modules/react-native-quick-crypto/src/random.ts
|
|
18
|
+
+++ b/node_modules/react-native-quick-crypto/src/random.ts
|
|
19
|
+
@@ -73,9 +73,20 @@ export function randomFillSync<T extends ABV>(
|
|
20
|
+
|
|
21
|
+
export function randomFillSync(buffer: ABV, offset: number = 0, size?: number) {
|
|
22
|
+
getNative();
|
|
23
|
+
- buffer = abvToArrayBuffer(buffer);
|
|
24
|
+
- const res = random.randomFillSync(buffer, offset, size ?? buffer.byteLength);
|
|
25
|
+
- buffer = res;
|
|
26
|
+
+ // Preserve the view's byte range before extracting the underlying ArrayBuffer.
|
|
27
|
+
+ // This is critical when buffer is a TypedArray view into a larger buffer
|
|
28
|
+
+ // (e.g. WebAssembly.Memory) — we must only fill the view's portion, not the
|
|
29
|
+
+ // entire underlying buffer.
|
|
30
|
+
+ const viewByteOffset = ArrayBuffer.isView(buffer) ? buffer.byteOffset : 0;
|
|
31
|
+
+ const viewByteLength = ArrayBuffer.isView(buffer) ? buffer.byteLength : buffer.byteLength;
|
|
32
|
+
+ const fillSize = size ?? viewByteLength;
|
|
33
|
+
+ // Create an owned ArrayBuffer so native code is not dependent on the original
|
|
34
|
+
+ // buffer reference staying valid (WASM memory growth can detach ArrayBuffers).
|
|
35
|
+
+ const owned = new ArrayBuffer(fillSize);
|
|
36
|
+
+ const res = random.randomFillSync(owned, 0, fillSize);
|
|
37
|
+
+ // Copy the random bytes back into the caller's buffer at the correct position
|
|
38
|
+
+ const src = abvToArrayBuffer(buffer);
|
|
39
|
+
+ new Uint8Array(src, viewByteOffset + offset, fillSize).set(new Uint8Array(res));
|
|
40
|
+
return buffer;
|
|
41
|
+
}
|
|
42
|
+
|
package/scripts/cli.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const command = process.argv[2];
|
|
5
|
+
|
|
6
|
+
switch (command) {
|
|
7
|
+
case 'setup-react-native':
|
|
8
|
+
require('./setup-react-native.js');
|
|
9
|
+
break;
|
|
10
|
+
default:
|
|
11
|
+
console.log('MindooDB CLI');
|
|
12
|
+
console.log('');
|
|
13
|
+
console.log('Usage:');
|
|
14
|
+
console.log(' npx mindoodb setup-react-native Set up MindooDB for React Native / Expo');
|
|
15
|
+
console.log('');
|
|
16
|
+
if (command) {
|
|
17
|
+
console.error(`Unknown command: ${command}`);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { execSync } = require('child_process');
|
|
7
|
+
const readline = require('readline');
|
|
8
|
+
|
|
9
|
+
// Resolve paths
|
|
10
|
+
const projectDir = process.cwd();
|
|
11
|
+
const mindoodbDir = path.dirname(__dirname); // node_modules/mindoodb
|
|
12
|
+
|
|
13
|
+
function ask(question) {
|
|
14
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
15
|
+
return new Promise(resolve => {
|
|
16
|
+
rl.question(question, answer => {
|
|
17
|
+
rl.close();
|
|
18
|
+
resolve(answer.trim().toLowerCase());
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function copyFileWithPrompt(src, dest, description) {
|
|
24
|
+
if (fs.existsSync(dest)) {
|
|
25
|
+
console.log(` [exists] ${path.relative(projectDir, dest)} (skipped)`);
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const destDir = path.dirname(dest);
|
|
29
|
+
if (!destDir) return false;
|
|
30
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
31
|
+
fs.copyFileSync(src, dest);
|
|
32
|
+
console.log(` [created] ${path.relative(projectDir, dest)}`);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function main() {
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log('MindooDB - React Native Setup');
|
|
39
|
+
console.log('=============================');
|
|
40
|
+
console.log('');
|
|
41
|
+
|
|
42
|
+
// Verify we're in a project directory
|
|
43
|
+
const projectPkgPath = path.join(projectDir, 'package.json');
|
|
44
|
+
if (!fs.existsSync(projectPkgPath)) {
|
|
45
|
+
console.error('Error: No package.json found in current directory.');
|
|
46
|
+
console.error('Run this command from your React Native project root.');
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const projectPkg = JSON.parse(fs.readFileSync(projectPkgPath, 'utf8'));
|
|
51
|
+
|
|
52
|
+
// ── Step 1: Copy patches ──────────────────────────────────────────────
|
|
53
|
+
console.log('Step 1: Copying patches...');
|
|
54
|
+
const patchesDir = path.join(mindoodbDir, 'patches');
|
|
55
|
+
const destPatchesDir = path.join(projectDir, 'patches');
|
|
56
|
+
|
|
57
|
+
if (fs.existsSync(patchesDir)) {
|
|
58
|
+
fs.mkdirSync(destPatchesDir, { recursive: true });
|
|
59
|
+
const patchFiles = fs.readdirSync(patchesDir).filter(f => f.endsWith('.patch') || f.endsWith('.md'));
|
|
60
|
+
for (const file of patchFiles) {
|
|
61
|
+
copyFileWithPrompt(
|
|
62
|
+
path.join(patchesDir, file),
|
|
63
|
+
path.join(destPatchesDir, file),
|
|
64
|
+
file
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
console.log(' Warning: patches directory not found in mindoodb package.');
|
|
69
|
+
console.log(' You may need to copy patches manually from the mindoodb repository.');
|
|
70
|
+
}
|
|
71
|
+
console.log('');
|
|
72
|
+
|
|
73
|
+
// ── Step 2: Install patch-package ─────────────────────────────────────
|
|
74
|
+
console.log('Step 2: Checking patch-package...');
|
|
75
|
+
const hasPatchPackage = !!(projectPkg.devDependencies?.['patch-package'] || projectPkg.dependencies?.['patch-package']);
|
|
76
|
+
if (!hasPatchPackage) {
|
|
77
|
+
const answer = await ask(' Install patch-package as a devDependency? (Y/n) ');
|
|
78
|
+
if (answer !== 'n') {
|
|
79
|
+
console.log(' Installing patch-package...');
|
|
80
|
+
try {
|
|
81
|
+
execSync('npm install --save-dev patch-package', { cwd: projectDir, stdio: 'inherit' });
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.error(' Failed to install patch-package. Please install it manually:');
|
|
84
|
+
console.error(' npm install --save-dev patch-package');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
console.log(' patch-package already installed.');
|
|
89
|
+
}
|
|
90
|
+
console.log('');
|
|
91
|
+
|
|
92
|
+
// ── Step 3: Add postinstall script ────────────────────────────────────
|
|
93
|
+
console.log('Step 3: Checking postinstall script...');
|
|
94
|
+
// Re-read package.json in case npm install changed it
|
|
95
|
+
const updatedPkg = JSON.parse(fs.readFileSync(projectPkgPath, 'utf8'));
|
|
96
|
+
if (!updatedPkg.scripts) updatedPkg.scripts = {};
|
|
97
|
+
if (!updatedPkg.scripts.postinstall) {
|
|
98
|
+
updatedPkg.scripts.postinstall = 'patch-package';
|
|
99
|
+
fs.writeFileSync(projectPkgPath, JSON.stringify(updatedPkg, null, 2) + '\n');
|
|
100
|
+
console.log(' Added "postinstall": "patch-package" to package.json');
|
|
101
|
+
} else if (!updatedPkg.scripts.postinstall.includes('patch-package')) {
|
|
102
|
+
console.log(` Warning: postinstall script exists but does not include patch-package:`);
|
|
103
|
+
console.log(` "${updatedPkg.scripts.postinstall}"`);
|
|
104
|
+
console.log(' Please add "patch-package" to your postinstall script manually.');
|
|
105
|
+
} else {
|
|
106
|
+
console.log(' postinstall script already configured.');
|
|
107
|
+
}
|
|
108
|
+
console.log('');
|
|
109
|
+
|
|
110
|
+
// ── Step 4: Install dependencies ──────────────────────────────────────
|
|
111
|
+
console.log('Step 4: Required dependencies...');
|
|
112
|
+
const requiredDeps = [
|
|
113
|
+
'react-native-automerge-generated',
|
|
114
|
+
'react-native-quick-crypto',
|
|
115
|
+
'react-native-nitro-modules',
|
|
116
|
+
'expo-standard-web-crypto',
|
|
117
|
+
'expo-crypto',
|
|
118
|
+
'text-encoding',
|
|
119
|
+
'react-native-url-polyfill',
|
|
120
|
+
'punycode',
|
|
121
|
+
'node-forge',
|
|
122
|
+
'tweetnacl',
|
|
123
|
+
'@babel/runtime',
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
const missingDeps = requiredDeps.filter(dep => {
|
|
127
|
+
return !updatedPkg.dependencies?.[dep] && !updatedPkg.devDependencies?.[dep];
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
if (missingDeps.length > 0) {
|
|
131
|
+
console.log(' The following dependencies are required but not installed:');
|
|
132
|
+
for (const dep of missingDeps) {
|
|
133
|
+
console.log(` - ${dep}`);
|
|
134
|
+
}
|
|
135
|
+
console.log('');
|
|
136
|
+
const answer = await ask(' Install these dependencies? (Y/n) ');
|
|
137
|
+
if (answer !== 'n') {
|
|
138
|
+
console.log(' Installing...');
|
|
139
|
+
try {
|
|
140
|
+
execSync(`npm install ${missingDeps.join(' ')}`, { cwd: projectDir, stdio: 'inherit' });
|
|
141
|
+
} catch (e) {
|
|
142
|
+
console.error(' Some dependencies failed to install. Please install them manually:');
|
|
143
|
+
console.error(` npm install ${missingDeps.join(' ')}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
console.log(' All required dependencies already installed.');
|
|
148
|
+
}
|
|
149
|
+
console.log('');
|
|
150
|
+
|
|
151
|
+
// ── Step 5: Copy template files ───────────────────────────────────────
|
|
152
|
+
console.log('Step 5: Copying starter files...');
|
|
153
|
+
const templatesDir = path.join(mindoodbDir, 'templates', 'reactnative');
|
|
154
|
+
if (fs.existsSync(templatesDir)) {
|
|
155
|
+
copyFileWithPrompt(
|
|
156
|
+
path.join(templatesDir, 'mindoodb-polyfills.js'),
|
|
157
|
+
path.join(projectDir, 'mindoodb-polyfills.js'),
|
|
158
|
+
'polyfills file'
|
|
159
|
+
);
|
|
160
|
+
} else {
|
|
161
|
+
console.log(' Warning: templates directory not found in mindoodb package.');
|
|
162
|
+
}
|
|
163
|
+
console.log('');
|
|
164
|
+
|
|
165
|
+
// ── Step 6: Check app.json ────────────────────────────────────────────
|
|
166
|
+
console.log('Step 6: Checking app.json...');
|
|
167
|
+
const appJsonPath = path.join(projectDir, 'app.json');
|
|
168
|
+
if (fs.existsSync(appJsonPath)) {
|
|
169
|
+
try {
|
|
170
|
+
const appJson = JSON.parse(fs.readFileSync(appJsonPath, 'utf8'));
|
|
171
|
+
const iosEngine = appJson?.expo?.ios?.jsEngine;
|
|
172
|
+
if (iosEngine === 'jsc') {
|
|
173
|
+
console.log(' ios.jsEngine is set to "jsc".');
|
|
174
|
+
console.log(' This is supported, and the bundled react-native patch addresses JSC ArrayBuffer issues.');
|
|
175
|
+
} else {
|
|
176
|
+
console.log(' Hermes (default) is recommended and works with native Automerge.');
|
|
177
|
+
}
|
|
178
|
+
} catch (e) {
|
|
179
|
+
console.log(' Could not parse app.json. Ensure your Expo app config is valid.');
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
console.log(' No app.json found. If using Expo, this is expected only in unusual project layouts.');
|
|
183
|
+
}
|
|
184
|
+
console.log('');
|
|
185
|
+
|
|
186
|
+
// ── Step 7: Print Metro config snippet ────────────────────────────────
|
|
187
|
+
console.log('Step 7: Metro configuration');
|
|
188
|
+
console.log('');
|
|
189
|
+
console.log(' Add the following to your metro.config.js:');
|
|
190
|
+
console.log('');
|
|
191
|
+
console.log(' ──────────────────────────────────────────────────');
|
|
192
|
+
const snippetPath = path.join(templatesDir, 'metro.config.snippet.js');
|
|
193
|
+
if (fs.existsSync(snippetPath)) {
|
|
194
|
+
const snippet = fs.readFileSync(snippetPath, 'utf8');
|
|
195
|
+
for (const line of snippet.split('\n')) {
|
|
196
|
+
console.log(` ${line}`);
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
console.log(' // See docs/reactnative.md for Metro configuration');
|
|
200
|
+
}
|
|
201
|
+
console.log(' ──────────────────────────────────────────────────');
|
|
202
|
+
console.log('');
|
|
203
|
+
|
|
204
|
+
// ── Summary ───────────────────────────────────────────────────────────
|
|
205
|
+
console.log('');
|
|
206
|
+
console.log('Setup complete! Next steps:');
|
|
207
|
+
console.log('');
|
|
208
|
+
console.log(' 1. Add `import "./mindoodb-polyfills";` at the very top of your entry point (index.js)');
|
|
209
|
+
console.log(' 2. Update your metro.config.js with the snippet above');
|
|
210
|
+
console.log(' 3. Initialize native Automerge in your entry point:');
|
|
211
|
+
console.log(' import { UseApi } from "@automerge/automerge/slim";');
|
|
212
|
+
console.log(' import { nativeApi } from "react-native-automerge-generated";');
|
|
213
|
+
console.log(' UseApi(nativeApi);');
|
|
214
|
+
console.log(' 4. Run `npx patch-package` to apply the patches');
|
|
215
|
+
console.log(' 5. Rebuild your native app (expo prebuild --clean && expo run:ios)');
|
|
216
|
+
console.log('');
|
|
217
|
+
console.log(' For a complete working example, see the template files:');
|
|
218
|
+
console.log(` ${path.relative(projectDir, path.join(mindoodbDir, 'templates', 'reactnative'))}/`);
|
|
219
|
+
console.log('');
|
|
220
|
+
console.log(' Full documentation:');
|
|
221
|
+
console.log(` ${path.relative(projectDir, path.join(mindoodbDir, 'docs', 'reactnative.md'))}`);
|
|
222
|
+
console.log('');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
main().catch(err => {
|
|
226
|
+
console.error('Setup failed:', err.message);
|
|
227
|
+
process.exit(1);
|
|
228
|
+
});
|