@microsoft/power-apps-native-offline
v0.1.26
Published
React Native SDK for Dataverse offline sync — extracted from PowerApps HostingSDK
Readme
@microsoft/power-apps-native-offline
React Native SDK for Dataverse Offline sync on iOS and Android.
Provides Dataverse Offline sync for Power Apps mobile clients as a self-contained package. It exposes JSI host functions to the React Native JS layer (initialize, synchronize, SQL batch execution, attachment handling, etc.) and bridges them to a native C++ sync engine via JNI (Android) and Obj-C++ (iOS).
Prerequisites
| Requirement | Version |
|-------------|---------|
| Node.js | 18+ |
| Java | 17 |
| Android NDK | 26.1.10909125 |
| CMake | 3.26+ |
| Xcode | 15+ (macOS only, for iOS) |
| CocoaPods | 1.14+ (macOS only, for iOS) |
| react-native | 0.83+ |
Architecture
Hermes (JS runtime)
│ calls
▼
global._DataverseOffline (JSI host functions)
│ dispatched via
▼
DataverseOfflineModule (Java ReactMethod + JSI bridge / Obj-C++ TurboModule)
│
▼
C++ sync engine (clientsync / dataverseOffline native libs)
│ makes HTTP calls through
▼
OfflineSDKHttpClient (OkHttp + BrotliInterceptorWithWeights)
│ → Dataverse backendBuilding & Releasing
npm scripts
| Command | What it does |
|---------|-------------|
| npm run clean | Remove build artifacts, vendor sources, stale tarballs |
| npm run bump | Patch version bump (e.g. 0.1.16 → 0.1.17) |
| npm run bump:minor | Minor version bump (e.g. 0.1.17 → 0.2.0) |
| npm run build:bundled | Bundle TS → JS (webpack) + generate type declarations |
| npm run build:native | Full native binary build (Android + iOS) + npm pack |
| npm run build:native:android | Android-only native build + npm pack |
| npm run release | Full release: clean → JS bundle → native build → .tgz |
| npm run release:android | Android-only release (faster, no macOS needed) |
Full Release Build
cd DataverseOfflineSDK
# 1. (Optional) Bump version
npm run bump
# 2. Build everything — outputs microsoft-power-apps-native-offline-X.Y.Z.tgz
npm run releaseThis single command:
- Cleans all build artifacts (
android/build,.cxx,.build-temp, old tarballs) - Bundles JS — webpack compiles TypeScript → production JS bundle + type declarations
- Syncs native sources — copies C++ from
../HostingSDK→vendor/hostingsdk/ - Builds Android — Gradle assembles release AAR for 3 ABIs (arm64-v8a, armeabi-v7a, x86_64), extracts
.sofiles - Builds iOS — Xcode compiles for device (arm64) + simulator (arm64, x86_64), creates
.xcframework - Packs tarball —
npm packwith allowlist excluding all source code
Android-Only Release (no macOS/Xcode needed)
npm run release:androidIndividual Build Steps
# Sync C++ sources (prerequisite for source builds)
./scripts/sync-native-sources.sh
# Build only the JS bundle + types
npm run build:bundled
# Build only Android AAR (release, 3 ABIs)
./gradlew :android:assembleReleaseInstalling in a Consumer App
npm install /path/to/microsoft-power-apps-native-offline-0.1.x.tgz --legacy-peer-deps
npx expo run:ios
npx expo run:androidWhat's in the Tarball
Included:
lib-bundled/— Bundled JS (single file, no TS source)lib/— TypeScript type declarations (.d.ts)android/src/main/java/— Java/Kotlin bridge codevendor-binaries/android/— Pre-built.sofor 3 ABIsvendor-binaries/RNDataverseOffline.xcframework/— Pre-built iOS static libraryRNDataverseOffline.podspec— CocoaPods integrationplugin/— Expo config pluginLICENSE,ThirdPartyNotices.txt
Excluded:
- All C++ source code (
vendor/hostingsdk/,android/src/main/jni/) - TypeScript source (
src/) - Build scripts, test files, sample apps, build artifacts
Dual-Mode Detection (Source vs Binary)
Consumer apps automatically use pre-built binaries. SDK developers compile from source:
| | Consumer App (npm install) | SDK Development |
|---|---|---|
| Android | Links .so from vendor-binaries/ | CMake compiles from src/main/jni/ |
| iOS | Links .xcframework | Compiles Obj-C++ + C++ from vendor/hostingsdk/ |
Testing
JVM tests (no device needed)
./gradlew :android:testCovers the JNI bridge contract, OkHttp client behaviour, and Brotli decompression interceptor.
Instrumented tests (device or emulator required)
./gradlew :android:connectedAndroidTestVerifies path plumbing and HTTP client construction with a real Android Context.
DDA (Direct Data Access) Client
Status: Design complete, implementation in progress.
DDA provides a client interface for querying and manipulating Dataverse offline data without MDL cache merging, so queries always reflect the actual SQLite database state.
Future usage (after implementation):
import { createDataverseClient } from '@microsoft/power-apps-native-offline';
const client = createDataverseClient({ debug: true });
// Query — returns accurate count from SQLite
const result = await client.retrieveMultipleRecordsAsync('accounts', {
filter: "name eq 'Contoso'",
orderBy: ['name asc'],
top: 100
});
// Write operations
await client.createRecordAsync('accounts', { name: 'New Account' });
await client.updateRecordAsync('accounts', 'guid', { name: 'Updated' });
await client.deleteRecordAsync('accounts', 'guid');Deferred work
| Task | Status |
|------|--------|
| Demo Mode B (pre-canned fixtures for real HTTP) | Backlog |
| TelemetryCallbackImpl — report sync events | Backlog |
| Foreground service — keep sync alive when backgrounded | Backlog |
| E2E integration tests against live Dataverse environment | Backlog |
| DDA Client implementation | In progress |
