feat(core): Use react-native-quick-base64 for envelope encoding when available#6314
feat(core): Use react-native-quick-base64 for envelope encoding when available#6314alwx wants to merge 4 commits into
Conversation
Semver Impact of This PR⚪ None (no version bump detected) 📋 Changelog PreviewThis is how your changes will appear in the changelog.
🤖 This preview updates automatically when you update the PR. |
f64591a to
383df08
Compare
|
After merging main, the base64 entry ended up under the released `## 8.15.0` section. Move it back under `## Unreleased` → `### Features` as flagged by DangerJS on #6314.
| /** | ||
| * Resolves the base64 encoder once. If the optional peer dependency | ||
| * `react-native-quick-base64` is installed, its native JSI encoder is used | ||
| * (~10x faster than the pure-JS fallback). Otherwise the bundled JS encoder |
There was a problem hiding this comment.
q: Is there a reference for the 10x claim?
There was a problem hiding this comment.
it's true that its not really verifyable, and also depends on a real device that uses it. the claim comes from the original issue but better be removed completely
…available Adds `react-native-quick-base64` as an optional peer dependency. When the package is installed by the consumer, envelope payloads are base64-encoded via its native JSI implementation (~10x faster than the bundled JS encoder). When it is absent, the SDK transparently falls back to the existing `base64-js`-derived encoder in `vendor/base64-js` — no behavior change for users who do not opt in. The encoder is resolved once at first use and cached, so the optional `require` runs at most once per session. Base64 encoding is on the hot path of `RNSentry.captureEnvelope` and is most impactful for large envelopes (profiles, attachments, replays). Closes #4884.
| "react": ">=17.0.0", | ||
| "react-native": ">=0.65.0" | ||
| "react-native": ">=0.65.0", | ||
| "react-native-quick-base64": ">=3.0.0" |
There was a problem hiding this comment.
Since we do not have any peer dependencies other react-native and expo, I am still skeptical on if we should add a dependency for this improvement.
Since RNSentry is a TurboModule and could accept the envelope bytes as binary across JSI on the new architecture what do you think of pursuing our own solution without a new dependency?
Looping @lucas-zimerman for more feedback on this 🙇
There was a problem hiding this comment.
The problem here is that it's a bit of reinventing the wheel.
Of course, Claude can do it easily but even the first not really working stage of it is already 1000+ lines of code (#6312) and I'm a bit sceptical about the maintenance load and the fact that a verified, well-tested and well-maintained solution which is react-native-quick-base64 works better than either we or Claude can do.
In addition, this is an optional peer dependency, people could still use the old approach if they don't want it.
antonis
left a comment
There was a problem hiding this comment.
Overall the changes on this PR look good. My main concern is if we should add a dependency since this has been avoided by design in the SDK till now.
After merging main, the base64 entry ended up under the released `## 8.15.0` section. Move it back under `## Unreleased` → `### Features` as flagged by DangerJS on #6314.
- Probe the native `fromByteArray` binding once at resolution so a broken native module (e.g. autolinking failed) falls through to the JS encoder instead of throwing on every `captureEnvelope`. - Drop the unverified "~10x faster" claim from the JSDoc. - Replace the sentinel-return test mock with a real base64 implementation and assert the actual encoded string, so the test verifies the encoding output and not just the routing. - Add a test covering the broken-native-module fallback path.
7cd554d to
503dd56
Compare
📢 Type of change
📜 Description
Adds
react-native-quick-base64as an optional peer dependency of@sentry/react-native. When the package is installed by the consumer, the SDK uses its native JSI base64 encoder (~10x faster than the bundled JS implementation) for envelope payloads on theRNSentry.captureEnvelopehot path. When the package is absent the SDK falls back to the existingbase64-js-derived encoder invendor/base64-js— no behavior change for users who do not opt in.Changes:
packages/core/src/js/utils/base64.ts—encodeToBase64()resolves the encoder once and caches it. Triesrequire('react-native-quick-base64')first; falls back tobase64StringFromByteArrayfromvendor/base64-js.packages/core/src/js/wrapper.ts—captureEnvelopenow callsencodeToBase64(envelopeBytes)instead ofbase64StringFromByteArray(envelopeBytes)directly.packages/core/package.json—react-native-quick-base64 >=3.0.0added topeerDependenciesand markedoptional: trueinpeerDependenciesMeta. No new required deps.CHANGELOG.md— entry under Unreleased / Features.💡 Motivation and Context
Closes #4884.
💚 How did you test it?
Addded tests!
📝 Checklist
sendDefaultPIIis enabled🔮 Next steps
react-native-quick-base64in the Sentry docs as a recommended performance install for users shipping large payloads.