restate / v1.0.0

Guarda cuando tú decidas

Guarda un store en IndexedDB o MMKV, cárgalo una vez al arrancar, guarda de forma explícita o automática y muestra los cambios sin guardar.

En esta páginaDeclara un store guardadoEspera una vez al arrancarGuardar, revertir y restablecerMuestra los cambios sin guardar y el progresoPruébaloGuarda automáticamenteAntes de cerrar la páginaGestiona los errores de almacenamiento

Declara un store guardado

Sustituye restate por persistedRestate y dale una key. Los componentes siguen usando el mismo hook y el mismo set.

El valor guardado se restaura automáticamente tras la creación. Editar cambia la memoria; no se escribe nada hasta que guardes o actives autoSave.

JavaScript / JSX
import { persistedRestate } from '@kkwaenggwari/restate';

export const useDraft = persistedRestate('', {
  key: 'article-draft',
  validate: (value) => typeof value === 'string',
});

Espera una vez al arrancar

En la entrada del cliente, importa la app y sus stores y espera a restateManager.ready antes de renderizar. Después, los componentes pueden leer directamente los valores guardados.

Que el almacenamiento no esté disponible, como durante el renderizado en servidor o en un navegador que lo bloquea, no es un fallo: esos stores funcionan en memoria. ready solo se rechaza cuando los registros no se pueden leer, migrar o validar.

JavaScript / JSX
import { createRoot } from 'react-dom/client';
import { restateManager } from '@kkwaenggwari/restate';
import App from './App';

async function start() {
  const root = createRoot(document.getElementById('root'));
  try {
    await restateManager.ready;
    root.render(<App />);
  } catch (error) {
    root.render(<p>Could not load saved data.</p>);
    console.error(error);
  }
}
start();

Guardar, revertir y restablecer

save escribe el valor actual, restore vuelve al valor guardado y resetAll vacía tanto la memoria como el almacenamiento. Todos devuelven una Promise.

JavaScript / JSX
await useDraft.save(); // write the current value
await useDraft.restore(); // return to the saved value
await useDraft.resetAndClearStorage(); // initial value in memory, record removed

Muestra los cambios sin guardar y el progreso

useStatus se vuelve a renderizar cuando cambia el estado de persistencia. dirty vale true mientras la memoria difiere del último valor cargado, guardado o restaurado. operation indica la operación de almacenamiento en curso.

Pasa un selector para volver a renderizar solo cuando cambie un campo.

JavaScript / JSX
function SaveButton() {
  const { dirty, operation, error } = useDraft.useStatus();
  const saving = operation === 'save';

  return (
    <>
      <button disabled={!dirty || saving} onClick={() => useDraft.save().catch(() => {})}>
        {saving ? 'Saving…' : 'Save'}
      </button>
      {error != null && <p>Could not save your draft.</p>}
    </>
  );
}

Pruébalo

Escribe, sube la latencia del almacenamiento y guarda. Vuelve a reproducir el ejemplo para ver cómo se restaura el borrador guardado.

Preparando el ejemplo…

Guarda automáticamente

Para ajustes y borradores que siempre deben persistir, actívalo una vez. autoSave: true guarda tras cada cambio; { delayMs } espera a que los cambios se detengan.

Una ráfaga de cambios se convierte en una sola escritura, y volver al valor guardado no escribe nada. Los fallos aparecen en status().error. Un scope de un componente escribe el cambio pendiente al desmontarse.

JavaScript / JSX
export const useTheme = persistedRestate('light', { key: 'theme', autoSave: true });

export const useDraft = persistedRestate('', {
  key: 'article-draft',
  autoSave: { delayMs: 500 },
});

Antes de cerrar la página

Lee el mismo estado fuera de React. Avisa antes de salir con cambios sin guardar, o guarda todo cuando la página se oculta.

JavaScript / JSX
window.addEventListener('beforeunload', (event) => {
  if (useDraft.status().dirty) event.preventDefault();
});

window.addEventListener('pagehide', () => {
  restateManager.saveAll();
});

Gestiona los errores de almacenamiento

Los errores de almacenamiento rechazan la Promise de la operación. Todos los errores de restate tienen un code y, en los stores guardados, la key del registro.

JavaScript / JSX
try {
  await useDraft.save();
} catch (error) {
  if (error.code === 'STORAGE_UNAVAILABLE') showNotice('Saving is off in this browser.');
  else if (error.code === 'STORAGE_VALUE_TOO_LARGE') showNotice('This draft is too large.');
  else showNotice(`Could not save "${error.key ?? 'draft'}".`);
}

Buscar en la documentación

Busca en títulos, descripciones y texto de todas las guías.