@reatom/persist
adapter for the Web Storage APIs.
npm i @reatom/persist-web-storage
Synchronizes atom state to the localStorage
with a given name
import { atom } from ' @reatom/framework '
import { withLocalStorage } from ' @reatom/persist-web-storage '
export const tokenAtom = atom ( '' , ' tokenAtom ' ) . pipe ( withLocalStorage ( ' token ' ))
Synchronizes atom state to the sessionsStorage
with a given name
import { atom } from ' @reatom/framework '
import { withSessionStorage } from ' @reatom/persist-web-storage '
export const tokenAtom = atom ( '' , ' tokenAtom ' ) . pipe ( withSessionStorage ( ' token ' ))
The main goal of this adapter is to synchronize atom between tabs without polluting localStorage
import { atom } from ' @reatom/framework '
import { withBroadcastChannel } from ' @reatom/persist-web-storage '
export const isAuthedAtom = atom ( '' , ' isAuthedAtom ' ) . pipe (
withBroadcastChannel ( ' isAuthedAtom ' ) ,
You can also give an instance of BroadcastChannel
import { atom } from ' @reatom/framework '
import { reatomPersistBroadcastChannel } from ' @reatom/persist-web-storage '
const myChannel = new BroadcastChannel ( ' customReusableChannel ' )
myChannel . onmessage ( ( event ) => {
const withMyBroadcastChannel = reatomPersistBroadcastChannel (myChannel)
export const isAuthedAtom = atom ( '' , ' isAuthedAtom ' ) . pipe (
withMyBroadcastChannel ( ' isAuthedAtom ' ) ,
IMPORTANT: The state currently flicks (goes from null
to actual value) on the first page load (due to asynchronous nature of IndexedDB and current synchronous architecture of @reatom/persist
)
The main goal of this adapter is to persist atom’s state to IndexedDB. withIndexedDb
does not currently support rich IndexedDB features such as indexing, transactions and migrations. It uses IndexedDB as a key-value storage, which is preferable over localStorage for large data (over a couple of megabytes).
import { reatomResource, withCache } from ' @reatom/framework '
import { withIndexedDb } from ' @reatom/persist-web-storage '
export const listResource = reatomResource (
async ( ctx ) => api . getList (ctx . spy (pageAtom)) ,
) . pipe ( withCache ( { withPersist: withIndexedDb } ))
You can also specify a custom database name and a custom `BroadcastChannel’ that will be used to synchronize the data in real time.
import { reatomResource, withCache } from ' @reatom/framework '
import { withIndexedDb } from ' @reatom/persist-web-storage '
export const listResource = reatomResource (
async ( ctx ) => api . getList (ctx . spy (pageAtom)) ,
) . pipe ( withIndexedDb ( { key: ' hugeListAtom ' , dbName: ' myCustomDb ' , channel } ))
If you want to avoid flickering, all you have to do is add a small delay after the atom is connected. Subscribe / spy the data atom, wait the ready atom and then use the actual data.
example↗
import { reatomResource, withCache, onConnect, sleep } from ' @reatom/framework '
import { withIndexedDb } from ' @reatom/persist-web-storage '
export const listResource = reatomResource (
async ( ctx ) => api . getList (ctx . spy (pageAtom)) ,
) . pipe ( withIndexedDb ( { key: ' hugeListAtom ' , dbName: ' myCustomDb ' , channel } ))
const isListReadyAtom = atom ( false , ' isListReadyAtom ' )
onConnect (listResource, async ( ctx ) => {
await ctx . schedule ( () => new Promise ( ( r ) => requestIdleCallback (r)))
isListReadyAtom (ctx, true )
return () => isListReadyAtom (ctx, false )
Synchronizes atom state to the document.cookie
with a given name.
When using withCookie
, the first argument it takes is an options object that allows you to configure various aspects of cookie behavior.
import { atom } from ' @reatom/framework '
import { withCookie } from ' @reatom/persist-web-storage '
interface CookieAttributes {
sameSite ?: ' strict ' | ' lax ' | ' none '
export const tokenAtom = atom ( "" , " tokenAtom " ) . pipe (