react-native-simple-queue
v1.0.0
Published
Offline request queue for React Native
Maintainers
Readme
React Native Simple Queue
A persistent, offline-first HTTP queue for React Native. It sends requests immediately when online and safely queues them when offline.
Installation
npm install react-native-simple-queue
npm install @react-native-async-storage/async-storage @react-native-community/netinfoQuick start
import { queue } from 'react-native-simple-queue';
queue.startAutoProcessing();
const result = await queue.addRequest(
'https://api.example.com/orders',
'POST',
{ productId: 'p-1' },
{ Authorization: 'Bearer token' },
{ idempotencyKey: 'create-order-42', priority: 'high' }
);
if (typeof result === 'object' && result !== null && 'queued' in result) {
console.log('Stored for sync:', result.id);
}Reliable retries and dead letters
Failed network requests and 408, 425, 429, and 5xx responses are queued even when the device initially appears online, then retried with exponential backoff. The automatic scheduler wakes up again when the next retry is due. Other 4xx responses are treated as permanent failures and moved to the dead-letter queue. Configure this policy per queue:
import { SimpleQueue } from 'react-native-simple-queue';
const ordersQueue = new SimpleQueue({
storageKey: '@my_app/orders',
retryPolicy: {
maxAttempts: 5,
initialDelayMs: 1_000,
maxDelayMs: 60_000,
backoffMultiplier: 2,
jitter: true,
},
maxQueueSize: 100,
maxBodySizeBytes: 100_000,
autoProcess: true,
});
const deadLetters = await ordersQueue.getDeadLetters();
await ordersQueue.retryDeadLetters();idempotencyKey prevents duplicate pending operations. It is especially important for non-idempotent actions such as creating an order or submitting a payment.
Axios
Axios is optional; the package does not install it for you. Pass any Axios-compatible instance to createAxiosSender:
import axios from 'axios';
import { SimpleQueue, createAxiosSender } from 'react-native-simple-queue';
const queue = new SimpleQueue({ sender: createAxiosSender(axios) });React hook
import { useQueue, queue } from 'react-native-simple-queue';
function SyncStatus() {
const { pending, deadLetters, isProcessing, process } = useQueue(queue);
return (
<Button
title={`Sync ${pending.length} requests`}
disabled={isProcessing}
onPress={() => void process()}
/>
);
}Security and storage
Queue entries can contain sensitive headers and request bodies. Avoid persisting secrets where possible. For sensitive workloads, pass an encrypted storage implementation instead of AsyncStorage:
import EncryptedStorage from 'react-native-encrypted-storage';
const secureQueue = new SimpleQueue({ storage: EncryptedStorage });Or wrap any QueueStorage implementation with your own platform crypto provider:
import AsyncStorage from '@react-native-async-storage/async-storage';
import { SimpleQueue, createSecureStorage } from 'react-native-simple-queue';
const storage = createSecureStorage(AsyncStorage, {
encrypt: async (plaintext) => encryptWithYourKey(plaintext),
decrypt: async (ciphertext) => decryptWithYourKey(ciphertext),
});
const secureQueue = new SimpleQueue({ storage });The storage implementation only needs getItem, setItem, and removeItem, so it can be replaced with your own encrypted or platform-specific adapter.
API
addRequest(url, method?, body?, headers?, options?): send immediately or queue offline.optionsacceptspriorityandidempotencyKey.enqueue(item): persist a fully configured request.processQueue(): process eligible queued items once.getPendingRequests(),clear(): inspect or clear pending requests.getDeadLetters(),retryDeadLetters(),clearDeadLetters(): manage permanent failures.startAutoProcessing(),stopAutoProcessing(): process automatically after a connection is restored.on(listener): subscribe to queue lifecycle events.
Development
npm test
npm run typescriptLicense
MIT © Aziz
