npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@authuser/http-react-native

v1.0.2

Published

Authuser HTTP React Native package for integrating with React Query, Async Storage, and MMKV.

Downloads

238

Readme

@authuser/http-react-native

Adaptador de React Native para @authuser/http-core, basado en @tanstack/react-query.
Incluye hooks declarativos (useHttpQuery, useHttpMutation) con soporte para:

  • Caché (memoria o persistente)
  • Reintentos automáticos
  • Rate limiting
  • Deduplicación de peticiones simultáneas
  • Middleware extensible
  • Tipado completo en TypeScript

📦 Instalación

npm install @authuser/http-react-native

Nota: Este paquete incluye todas las dependencias necesarias (@authuser/http-core, @tanstack/react-query, @react-native-async-storage/async-storage, axios). No necesitas instalar nada más.

🚀 Uso básico

1. Crea el HttpService

// src/lib/http.ts
import { HttpService, AxiosHttpClient } from '@authuser/http-core';
import {
	AsyncStorageCache,
	AsyncStorageSession,
	AsyncStoragePersistence,
} from '@authuser/http-react-native';
import Config from 'react-native-config';

// Usar el Bundle ID de tu app como prefijo (recomendado)
const APP_ID = 'com.mycompany.myapp'; // ← Tu Bundle ID

export const http = new HttpService({
	client: new AxiosHttpClient(),
	session: new AsyncStorageSession(),
	cache: new AsyncStorageCache(`${APP_ID}.cache.`), // caché temporal con TTL
	persistence: new AsyncStoragePersistence(`${APP_ID}.persist.`), // persistencia permanente
	config: {
		baseUrl: Config.BASE_URL ?? '',
		cache: { enabled: true, ttlMs: 60_000 },
		retry: {
			enabled: true,
			maxAttempts: 1,
			delay: 500,
			backoff: 'exponential',
			skipOnEndpoint: ['/auth/login'],
			skipOnStatusCode: [401, 429],
		},
	},
});

2. Envuelve tu aplicación

// App.tsx
import { HttpProvider } from '@authuser/http-react-native';
import { http } from './lib/http';
import MainApp from './MainApp';

export default function App() {
	return (
		<HttpProvider service={http}>
			<MainApp />
		</HttpProvider>
	);
}

💡 Nota: HttpProvider ya incluye internamente QueryClientProvider, por lo que solo necesitas un provider.

Configuración avanzada (opcional)

Si necesitas personalizar el QueryClient:

import { HttpProvider } from '@authuser/http-react-native';
import { QueryClient } from '@tanstack/react-query';
import { http } from './lib/http';
import MainApp from './MainApp';

const queryClient = new QueryClient({
	defaultOptions: {
		queries: {
			staleTime: 60_000, // 1 minuto
			cacheTime: 300_000, // 5 minutos
		},
	},
});

export default function App() {
	return (
		<HttpProvider service={http} queryClient={queryClient}>
			<MainApp />
		</HttpProvider>
	);
}

🧪 Hooks disponibles

🔍 useHttpQuery

| Característica | Valor | | ------------------ | ------------------------------------ | | Basado en | useQuery | | Caché automática | ✅ Sí (memoiza resultados por clave) | | Reintentos | ✅ Sí (según config retry) | | Refetch automático | ✅ Sí (focus / reconexión) | | Uso típico | GET / datos |

import { useHttpQuery } from '@authuser/http-react-native';

// Ejemplo básico con caché temporal
const { data, isLoading, error } = useHttpQuery<User[]>({ url: '/users', cache: true });

// Con persistencia offline-first
const { data, isLoading, error } = useHttpQuery<User[]>({
	url: '/user/profile',
	persist: true,
	persistKey: 'user-profile',
});

// Con query params y opciones de React Query
const { data, isLoading, error } = useHttpQuery<User[]>(
	{ url: '/users', query: { role: 'admin' } },
	{ staleTime: 30_000, refetchOnWindowFocus: false }
);

Parámetros:

  • req: Objeto HttpRequest sin method (o con method: 'GET' opcional)
  • opts: Opciones de useQuery de React Query (omitiendo queryKey y queryFn)

✏️ useHttpMutation

| Característica | Valor | | -------------- | --------------------------- | | Basado en | useMutation | | Caché | ❌ No | | Refetch | ❌ No automático | | Uso típico | POST / PUT / PATCH / DELETE |

import { useHttpMutation } from '@authuser/http-react-native';

const { mutate, isPending, isSuccess } = useHttpMutation();

mutate({
	url: '/users',
	method: 'POST',
	body: { name: 'Neo' },
});

🔁 RetryConfig

type RetryConfig = {
	enabled?: boolean;
	maxAttempts?: number;
	delay?: number;
	backoff?: 'linear' | 'exponential' | 'fixed';
	skipOnStatusCode?: number[];
	skipOnEndpoint?: string[];
	onRetry?: (retryCount: number, error: AxiosError, config: any) => void;
};

🧱 Tipos avanzados

type User = { id: string; name: string };
type NewUser = { name: string };

const { data } = useHttpQuery<User[]>({ url: '/users' });
const { mutate } = useHttpMutation<User, NewUser>();

🧠 Resumen práctico

| Caso | Hook recomendado | | ----------------------------- | ----------------- | | Obtener lista de productos | useHttpQuery | | Obtener detalle de un vídeo | useHttpQuery | | Crear nuevo usuario | useHttpMutation | | Enviar formulario de contacto | useHttpMutation | | Actualizar perfil de usuario | useHttpMutation | | Borrar comentario | useHttpMutation |

🔑 Prefijos y Organización

Tanto AsyncStorageCache como AsyncStoragePersistence aceptan un prefijo opcional para organizar las claves en AsyncStorage:

// ✅ Opción 1: Sin prefijo (usa '__http_cache__' y 'http-persist:' por defecto)
const cache = new AsyncStorageCache();
const persistence = new AsyncStoragePersistence();

// ✅ Opción 2: Con Bundle ID (recomendado para apps en producción)
const APP_ID = 'com.mycompany.myapp';
const cache = new AsyncStorageCache(`${APP_ID}.cache.`);
const persistence = new AsyncStoragePersistence(`${APP_ID}.persist.`);

// ✅ Opción 3: Con prefijos personalizados
const cache = new AsyncStorageCache('myapp-cache-');
const persistence = new AsyncStoragePersistence('myapp-persist-');

¿Por qué usar el Bundle ID?

  1. Evita colisiones: Si tienes múltiples apps o módulos
  2. Identificación clara: Las claves en AsyncStorage son fáciles de identificar
  3. Convención estándar: Similar a UserDefaults en iOS o SharedPreferences en Android

Ejemplo de claves generadas

// Con Bundle ID 'com.mycompany.myapp'
const cache = new AsyncStorageCache('com.mycompany.myapp.cache.');
const persistence = new AsyncStoragePersistence('com.mycompany.myapp.persist.');

// Generará claves como:
// 'com.mycompany.myapp.cache.:GET|/user/profile||'
// 'com.mycompany.myapp.persist.:user-profile'

🌐 Persistencia Offline-First

El paquete incluye soporte para persistencia permanente de respuestas, ideal para apps móviles que necesitan funcionar sin conexión:

AsyncStoragePersistence

Almacena respuestas HTTP de forma permanente en AsyncStorage para acceso offline:

import { AsyncStoragePersistence } from '@authuser/http-react-native';

// En tu configuración de HttpService
const persistence = new AsyncStoragePersistence('myapp-');

const http = new HttpService({
	client: new AxiosHttpClient(),
	persistence,
	config: { baseUrl: Config.BASE_URL, retry: { enabled: true } },
});

Ejemplo de uso en pantallas

import { useHttpQuery } from '@authuser/http-react-native';
import { useState, useEffect } from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
import NetInfo from '@react-native-community/netinfo';

function UserProfileScreen() {
	const [isOffline, setIsOffline] = useState(false);

	// Petición con persistencia - funcionará offline
	const {
		data: profile,
		isLoading,
		error,
	} = useHttpQuery<UserProfile>({
		url: '/user/profile',
		persist: true,
		persistKey: 'user-profile',
		requiresAuth: true,
	});

	useEffect(() => {
		// Monitorear conexión
		const unsubscribe = NetInfo.addEventListener((state) => {
			setIsOffline(!state.isConnected);
		});

		return () => unsubscribe();
	}, []);

	if (isLoading) return <ActivityIndicator size="large" />;

	return (
		<View>
			{isOffline && (
				<View style={styles.offlineBanner}>
					<Text>📴 Modo Offline - Mostrando datos guardados</Text>
				</View>
			)}
			{profile && (
				<View>
					<Text style={styles.name}>{profile.name}</Text>
					<Text style={styles.email}>{profile.email}</Text>
				</View>
			)}
		</View>
	);
}

Casos de uso comunes en móviles

// 1. Perfil del usuario (siempre disponible)
const { data: profile } = useHttpQuery({
	url: '/user/profile',
	persist: true,
	persistKey: 'user-profile',
	requiresAuth: true,
});

// 2. Configuración de la app
const { data: config } = useHttpQuery({
	url: '/config/app',
	persist: true,
	persistKey: 'app-config',
});

// 3. Catálogo de productos (e-commerce offline)
const { data: products } = useHttpQuery({
	url: '/products',
	query: { category: 'electronics' },
	persist: true,
	persistKey: 'products-electronics',
});

// 4. Contenido para lectura offline (noticias, artículos)
const { data: articles } = useHttpQuery({
	url: '/articles/latest',
	persist: true,
	persistKey: 'latest-articles',
});

// 5. Datos de dashboard
const { data: metrics } = useHttpQuery({
	url: '/dashboard/metrics',
	persist: true,
	persistKey: 'dashboard-metrics',
	cache: true, // También usar caché para performance
});

⚠️ Diferencia entre Cache y Persistencia

| | Cache | Persistencia | | -------------------- | -------------- | --------------------- | | Duración | Temporal (TTL) | Permanente | | Propósito | Performance | Soporte offline | | Expira | ✅ Sí | ❌ No | | Fallback offline | ❌ No | ✅ Sí | | Actualización | Después de TTL | Cada petición exitosa | | Storage | AsyncStorage | AsyncStorage |

Recomendación: Usa cache: true + persist: true para máximo performance Y soporte offline.

🔄 Sincronización automática

La persistencia se actualiza automáticamente cuando:

  • ✅ La app recupera conexión
  • ✅ El usuario hace pull-to-refresh
  • ✅ React Query refetch automático
import { useHttpQuery } from '@authuser/http-react-native';
import { RefreshControl, ScrollView } from 'react-native';

function ProductList() {
	const {
		data: products,
		isLoading,
		refetch,
	} = useHttpQuery({
		url: '/products',
		persist: true,
		persistKey: 'products',
	});

	return (
		<ScrollView
			refreshControl={<RefreshControl refreshing={isLoading} onRefresh={() => refetch()} />}
		>
			{/* Renderiza productos */}
		</ScrollView>
	);
}

🧩 Personalización

Usar tu propio SessionManagerPort:

new HttpService({
	client: new AxiosHttpClient(),
	session: new MyCustomSessionManager(),
	config: { baseUrl: '/api' },
});

Usar caché persistente:

new HttpService({
	client,
	cache: new AsyncStorageCache(), // implementa CachePort
	config,
});

🎯 Exportaciones del paquete

export { useHttpQuery } from './hooks/useHttpQuery';
export { useHttpMutation } from './hooks/useHttpMutation';
export { HttpProvider, useHttpService } from './provider/HttpContext';
export { AsyncStorageCache } from './infrastructure/AsyncStorageCache';
export { AsyncStoragePersistence } from './infrastructure/AsyncStoragePersistence';
export { AsyncStorageSession } from './infrastructure/AsyncStorageSession';

📁 Estructura recomendada

src/
├─ lib/
│  ├─ http.ts               ← instancia de HttpService
│  └─ session.ts            ← implementación de SessionManager
├─ screens/
│  └─ Users.tsx             ← useHttpQuery
├─ App.tsx
└─ main.tsx                 ← montaje de providers

🧪 Testing

Mockea HttpService o usa msw + @tanstack/react-query/testing.
Puedes usar el helper createTestQueryClient() para pruebas unitarias.

🛠️ Dependencias

Dependencies (incluidas automáticamente)

  • @authuser/http-core: ^1.6.0 (incluye axios)
  • @tanstack/react-query: ^5.0.0
  • @react-native-async-storage/async-storage: ^2.2.0

Peer Dependencies (debes tenerlas en tu proyecto)

  • react: >=18.0.0
  • react-native: >=0.70.0

✨ Instalación simple: Un solo comando instala todo lo necesario.