Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
To be clear: I don't expect this to merge.
I spent roughly 2 days implementing this, because I wanted to:
What is this? 🤔
An example Expo app located in
./example
Importing "react-native-automerge" will inject the binding via the
use
export from@automerge/automerge
.A Uniffi binding located in
./rust/src/lib.rs
This file provides the Rust code backing the implementation of the
Automerge
class.It's purpose is equivalent of that of the Automerge WASM binding's ./rust/automerge-wasm/src/lib.rs and this has served as an inspiration for much of the code.
The
react-native-automerge
package./package
./package/src/index.ts
(injected into the Automerge SDK by calling theuse
function).Automerge
class located in./package/src/Automerge.ts
This file provides the Rust code backing the implementation of the
Automerge
class.It's purpose is equivalent of that of the Automerge WASM binding's ./rust/automerge-wasm/src/lib.rs and this has served as an inspiration for much of the code.
How does it even work? 🤷
The
uniffi-bindgen-react-native
toolAll of the code in 2 and 3 integrate with React Native Core APIs (either the platform specific APIs to register the TurboModule or the JS runtime via JSI) and it must be built on the developers machine, to use the correct API and ABIs declared by the exact React Native version that the developer is using to build their app.
How do I test / run it? 🏃
Note: I've been using iOS when developing this and I have no idea what the state of the Android build is.
uniffi-bindgen-react-native
's pre-install guide.npm install
).node_modules/@automerge/automerge/package.json
by adding thisreact-native
main field"react-native": "./dist/mjs/entrypoints/slim.js",
, just below the"main"
property.npm run uniffi:ios --prefix package
)npm run build --prefix package
)npm run ios --prefix example
)Caveats and drawbacks 🥺
Result
+Err
pattern which would give more pleasant runtime errors.materialize
function, which currently returns aMap<string, string>
but would have to return some "wrapper" which would be called to construct arbitrary JS values on the JS-side - not ideal is this will likely bring significant overhead for large documents.applyAndReturnPatches
function, which in the WASM binding mutates the object in Rust code (calling out to the JS runtime via the wasmbindgen's runtime). This is not possible in the Uniffi binding and insteaddiffIncremental()
is called and then the patches are applying on the JS-side. I actually suspect this might be faster than what the WASM binding is doing, because it doesn't need a call from native to JS on every change to the doc.Key takeaways 💡