@nanostores/persistent
Version:
A store for Nano Stores state manager to keep data in localStorage
212 lines (194 loc) • 4.7 kB
TypeScript
import type { MapStore, WritableAtom } from 'nanostores'
export type PersistentStore = Record<string, string>
export interface PersistentEvent {
key: string
newValue: string
}
export interface PersistentListener {
(e: PersistentEvent): void
}
export interface PersistentEvents {
addEventListener(
key: string,
callback: PersistentListener,
restore: () => void
): void
perKey?: boolean
removeEventListener(
key: string,
callback: PersistentListener,
restore: () => void
): void
}
/**
* Replace localStorage to keep persistent data.
*
* @param storage An object with localStorage API.
* @param events An object with `addEventListener` and `removeEventListener`.
*/
export function setPersistentEngine(
storage: PersistentStore,
events: PersistentEvents
): void
/**
* `window` events to be used in `setPersistentEngine`.
*/
export const windowPersistentEvents: PersistentEvents
export interface PersistentEncoder<Origin = any> {
/**
* Decoder to convert value from string.
*/
decode: (encoded: string) => Origin
/**
* Encoder to convert value to string.
*/
encode: (value: Origin) => string
}
interface PersistentSimpleOptions {
/**
* Does not synchronize changes from other browser tabs
*/
listen?: boolean
}
export type PersistentOptions =
| (PersistentEncoder & PersistentSimpleOptions)
| PersistentSimpleOptions
interface PersistentMapFactory {
/**
* Keep key-value data in localStorage.
*
* ```ts
* import { persistentMap } from '@nanostores/persistent'
*
* export const settings = persistentMap<{
* theme: 'dark' | 'light'
* favorite: string
* }>('settings:', { theme: 'light' })
* ```
*
* @param prefix Key prefix in localStorage.
* @param initial Initial value on missed data in localStorage.
* @param opts Store options.
* @return The store.
*/
<Value extends Record<string, string | undefined>>(
name: string,
initial?: Value,
opts?: PersistentSimpleOptions
): MapStore<Value>
<Value extends object>(
name: string,
initial: Value,
opts: PersistentEncoder<Value[keyof Value]> & PersistentSimpleOptions
): MapStore<Value>
}
export const persistentMap: PersistentMapFactory
interface PersistentAtomFactory {
/**
* Store a value in localStorage.
*
* For key-value objects use {@link persistentMap}.
*
* ```ts
* import { persistentAtom } from '@nanostores/persistent'
*
* export const locale = persistentAtom<string>('locale', 'en')
* ```
*
* @param name Key name in localStorage.
* @param initial Initial value on missed data in localStorage.
* @param opts Store options.
* @return The store.
*/
<Value extends string | undefined>(
name: string,
initial?: Value,
opts?: PersistentSimpleOptions
): WritableAtom<Value>
<Value>(
name: string,
initial: Value,
opts: PersistentEncoder<Value> & PersistentSimpleOptions
): WritableAtom<Value>
}
export const persistentAtom: PersistentAtomFactory
/**
* Enable fake storage to test persistent stores.
*
* ```js
* import { useTestStorageEngine } from '@nanostores/persistent'
*
* beforeAll(() => {
* useTestStorageEngine()
* })
* ```
*/
export function useTestStorageEngine(): void
/**
* Set fake storage key to test persistent store.
*
* ```js
* import {
* useTestStorageEngine,
* setTestStorageKey,
* cleanTestStorage
* } from '@nanostores/persistent'
*
* beforeAll(() => {
* useTestStorageEngine()
* })
*
* beforeEach(() => {
* cleanTestStorage()
* })
*
* it('listens for changes', () => {
* setTestStorageKey('settings:locale', 'ru')
* expect(settings.get()).toEqual({ locale: 'ru' })
* })
* ```
*
* @param key Full name of key in localStorage.
* @param newValue New value of the key.
*/
export function setTestStorageKey(
key: string,
newValue: string | undefined
): void
/**
* Get full content of fake storage to test persistent stores.
*
* ```js
* import {
* useTestStorageEngine,
* cleanTestStorage,
* getTestStorage,
* } from '@nanostores/persistent'
*
* beforeAll(() => {
* useTestStorageEngine()
* })
*
* beforeEach(() => {
* cleanTestStorage()
* })
*
* it('changes storage', () => {
* settings.setKey('locale')
* expect(getTestStorage()).toEqual({ 'settings:locale': 'ru' })
* })
* ```
*/
export function getTestStorage(): Record<string, string>
/**
* Clean test storage used to test persistent stores.
*
* ```js
* import { cleanTestStorage } from '@nanostores/persistent'
*
* afterEach(() => {
* cleanTestStorage()
* })
* ```
*/
export function cleanTestStorage(): void