Hooks

Los hooks se registran en un cliente, se ejecutan en orden de registro y pueden ser síncronos o asíncronos. No son opciones de configuración por solicitud.

import { Http } from "fetchzen";
const api = Http.create("https://api.example.com", {
cache: false,
hooks: {
request: [
({ url, init }) => {
init.headers.set("X-Request-Id", crypto.randomUUID());
return { url, init };
},
],
response: [
(response) => {
console.info("Estado HTTP", response.status);
},
],
error: [
(error) => {
console.error(error.message);
},
],
},
});
await api.get("/users");
HookRecibeValor devuelto
request{ url, init }, después de preparar encabezados, cuerpo y URLUn contexto reemplaza URL/init; un Response omite la red y los hooks de solicitud restantes.
response(response, context), antes de procesar el cuerpo y validar el presetUn Response reemplaza la respuesta que usarán los siguientes hooks y el procesamiento.
error(error, context)Un Error reemplaza el error que recibe quien hizo la llamada.

No devolver nada conserva el contexto, la respuesta o el error actual. Los hooks de error no recuperan un resultado exitoso: la solicitud sigue rechazándose (o regresa el error en el objeto de safe). Los hooks de solicitud se ejecutan una vez, no en cada reintento. Los de respuesta ven la respuesta final, no las intermedias de los reintentos.

Con el cliente anterior, hook() devuelve una función para cancelar el registro. Elimina los hooks temporales cuando ya no se necesiten para evitar duplicados en clientes de larga duración.

const off = api.hook("request", ({ init }) => {
init.headers.set("X-Feature", "preview");
});
await api.get("/users");
off();

Cada función de cancelación elimina únicamente su propio registro, incluso si el mismo callback se registró varias veces. Llamarla de nuevo no hace nada. Las solicitudes que ya están en curso conservan su instantánea original de hooks.

Las consultas compartidas con Http.create reutilizan el cliente y sus hooks; la inicialización posterior no los reemplaza ni agrega otros. Usa hook() y su función de cancelación, no configure({ hooks: ... }). Cada solicitud toma una instantánea de los valores y todas las listas de hooks al comenzar, incluidos los hooks de respuesta/error. Los cambios afectan solo solicitudes posteriores, no el estado mutable de los callbacks. Para hooks por usuario en SSR, usa clientes privados con cache: false, no estado global o de módulo.

Un hook de solicitud puede devolver un Response normal de Fetch. Los hooks de respuesta, la lectura del cuerpo y las validaciones del preset y del esquema siguen ejecutándose:

const offLocal = api.hook("request", ({ url }) => {
if (new URL(url).pathname === "/health") {
return Response.json({ data: { healthy: true } });
}
});
await api.get("/health");
offLocal();

Crea una respuesta nueva o clona una almacenada para cada solicitud; no puedes reutilizar una respuesta consumida. Esto reemplaza el transporte, no es una caché de respuestas integrada.

Los registros son independientes de los hooks y están desactivados por defecto. Actívalos con log: true en la instancia o solicitud. Configura un logger propio en la instancia:

import { Http } from "fetchzen";
const api = Http.create("https://api.example.com", {
cache: false,
log: true,
logger: {
request: ({ init }) => console.debug(init.method),
response: ({ response, duration }) => console.debug(response.status, duration),
error: ({ error }) => console.error(error.name),
},
});
await api.get("/health");

duration mide milisegundos hasta terminar de procesar el cuerpo, no solo la latencia de red. El registro de respuesta ocurre antes de validar el preset/esquema, así que puede ir seguido de un registro de error.

El logger integrado oculta los encabezados authorization, proxy-authorization, cookie, set-cookie, x-api-key y x-auth-token. No oculta las URLs, los cuerpos ni los detalles de los errores. Los loggers personalizados reciben datos sin ocultar; usa redactHeaders al registrar encabezados y aplica tus propias reglas al resto.

Consulta errores para conocer su identidad y reintentos para revisar su comportamiento. Prueba el ejemplo de hooks.