3.4.1 • Published 6 days ago

@reatom/persist-web-storage v3.4.1

Weekly downloads
-
License
MIT
Repository
github
Last release
6 days ago

@reatom/persist adapter for the Web Storage APIs.

Installation

npm i @reatom/persist-web-storage

Usage

withLocalStorage

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'))

withSesssionStorage

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'))

withBroadcastChannel

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) => {
  console.log(event)
  // Do some work here
  // ...
})

const withMyBroadcastChannel = reatomPersistBroadcastChannel(myChannel)


export const isAuthedAtom = atom('', 'isAuthedAtom').pipe(
  withMyBroadcastChannel('isAuthedAtom'),
)

withIndexedDb

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)),
  'listResource',
).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)),
  'listResource',
).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)),
  'listResource',
).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)
})

withCookie

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 {
  maxAge?: number
  expires?: Date
  path?: string
  domain?: string
  secure?: boolean
  sameSite?: 'strict' | 'lax' | 'none'
}

export const tokenAtom = atom("", "tokenAtom").pipe(
  withCookie({
    maxAge: 3600, // 1 hour
  })("token"),
);
3.4.1

6 days ago

3.4.0

8 days ago

3.3.4

27 days ago

3.3.3

2 months ago

3.3.2

2 months ago

3.3.1

3 months ago

3.3.0

3 months ago

3.2.2

10 months ago

3.2.3

10 months ago

3.2.0

1 year ago