React Native offline transactions
I was successfully able to make the new offline-transactions package work in my react native project.
Claude summarized the following hacks/workarounds that were required to get it to work:
I thought this might help other people trying to make things work in a react native context. Would there be interest in supporting this natively by the package?
Claude summarized the following hacks/workarounds that were required to get it to work:
Here are the React Native-specific hacks/fixes for @tanstack/offline-transactions:
1. offline-polyfill.ts - Browser API stubs
The library expects browser APIs that don't exist in React Native:
// Stub document (visibility detection)
globalThis.document = { addEventListener: () => {}, hidden: false, ... }
// Stub window (online/offline events)
globalThis.window = { addEventListener: () => {}, navigator: { onLine: true }, ... }
2. ReactNativeLeaderElection class - Multi-tab coordination
The library uses WebLocks or BroadcastChannel for multi-tab coordination. React Native has neither, so we implement a simple leader election that always returns "leader":
class ReactNativeLeaderElection implements LeaderElection {
// Always leader since RN is single-instance
isLeader(): boolean { return true }
onLeadershipChange(callback) { callback(true); ... }
}
3. asyncStorageAdapter - Storage backend
The library defaults to IndexedDB with localStorage fallback. React Native has neither, so we implement the StorageAdapter interface with AsyncStorage.
4. Pre-initialization timing
The executor initializes asynchronously but the library's default behavior assumes sync initialization. We add a 100ms delay + pre-initialize at app startup to ensure leadership is established before any actions run.Here are the React Native-specific hacks/fixes for @tanstack/offline-transactions:
1. offline-polyfill.ts - Browser API stubs
The library expects browser APIs that don't exist in React Native:
// Stub document (visibility detection)
globalThis.document = { addEventListener: () => {}, hidden: false, ... }
// Stub window (online/offline events)
globalThis.window = { addEventListener: () => {}, navigator: { onLine: true }, ... }
2. ReactNativeLeaderElection class - Multi-tab coordination
The library uses WebLocks or BroadcastChannel for multi-tab coordination. React Native has neither, so we implement a simple leader election that always returns "leader":
class ReactNativeLeaderElection implements LeaderElection {
// Always leader since RN is single-instance
isLeader(): boolean { return true }
onLeadershipChange(callback) { callback(true); ... }
}
3. asyncStorageAdapter - Storage backend
The library defaults to IndexedDB with localStorage fallback. React Native has neither, so we implement the StorageAdapter interface with AsyncStorage.
4. Pre-initialization timing
The executor initializes asynchronously but the library's default behavior assumes sync initialization. We add a 100ms delay + pre-initialize at app startup to ensure leadership is established before any actions run.I thought this might help other people trying to make things work in a react native context. Would there be interest in supporting this natively by the package?