Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/react18-tools/persist-and-sync
Zustand middleware to easily persist and sync Zustand state between tabs / windows / iframes (Same Origin)
https://github.com/react18-tools/persist-and-sync
javascript mayank1513 middleware persist-and-sync persistent-storage react react-library react18 react18-tools typescript typescript-library typescript-react zustand
Last synced: 4 months ago
JSON representation
Zustand middleware to easily persist and sync Zustand state between tabs / windows / iframes (Same Origin)
- Host: GitHub
- URL: https://github.com/react18-tools/persist-and-sync
- Owner: react18-tools
- License: mit
- Created: 2023-08-27T03:45:36.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-04-18T08:41:07.000Z (10 months ago)
- Last Synced: 2024-10-01T00:42:52.964Z (4 months ago)
- Topics: javascript, mayank1513, middleware, persist-and-sync, persistent-storage, react, react-library, react18, react18-tools, typescript, typescript-library, typescript-react, zustand
- Language: TypeScript
- Homepage: https://persist-and-sync.vercel.app
- Size: 69.3 KB
- Stars: 32
- Watchers: 1
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# Persist-And-Sync Zustand Store
[![test](https://github.com/react18-tools/persist-and-sync/actions/workflows/test.yml/badge.svg)](https://github.com/react18-tools/persist-and-sync/actions/workflows/test.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/5355eb02cfedc9184e3f/maintainability)](https://codeclimate.com/github/mayank1513/persist-and-sync/maintainability) [![codecov](https://codecov.io/gh/mayank1513/persist-and-sync/graph/badge.svg)](https://codecov.io/gh/mayank1513/persist-and-sync) [![Version](https://img.shields.io/npm/v/persist-and-sync.svg?colorB=green)](https://www.npmjs.com/package/persist-and-sync) [![Downloads](https://img.jsdelivr.com/img.shields.io/npm/d18m/persist-and-sync.svg)](https://www.npmjs.com/package/persist-and-sync) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/persist-and-sync)
> Zustand middleware to easily persist and sync Zustand state between tabs/windows/iframes (Same Origin)
> Motivation: Recently I got caught up in several issues working with the persist middleware and syncing tabs with Zustand. This is a simple lightweight middleware to persist and instantly share state between tabs or windows
- ✅ 🐙 ~ 1 kB size cross-tab state sharing + persistence for zustand
- ✅ Full TypeScript Support
- ✅ solid reliability in 1 writing and n reading tab scenarios (with changing writing tab)
- ✅ Fire and forget approach of always using the latest state. Perfect for single-user systems
- ✅ Share state between multiple browsing contexts
- ✅ Additional control over which fields to `persist-and-sync` and which to ignore
- ✅ Optimized for performance using memoization and closures.
- ✅ Update options at runtime by setting `__persistNSyncOptions` in your store.## Install
```bash
$ pnpm add persist-and-sync
```**or**
```bash
$ npm install persist-and-sync
```**or**
```bash
$ yarn add persist-and-sync
```## Usage
Add the middleware while creating the store and the rest will be taken care.
```ts
import { create } from "zustand";
import { persistNSync } from "persist-and-sync";type MyStore = {
count: number;
set: (n: number) => void;
};const useStore = create(
persistNSync(
set => ({
count: 0,
set: n => set({ count: n }),
}),
{ name: "my-example" },
),
);
```⚡🎉Boom! Just a couple of lines and your state perfectly syncs between tabs/windows and it is also persisted using `localStorage`!
## Advanced Usage (Customizations)
### PersistNSyncOptions
In several cases, you might want to exclude several fields from syncing. To support this scenario, we provide a mechanism to exclude fields based on a list of fields or regular expressions.
```typescript
type PersistNSyncOptionsType = {
name: string;
/** @deprecated */
regExpToIgnore?: RegExp;
include?: (string | RegExp)[];
exclude?: (string | RegExp)[];
storage?: "localStorage" | "sessionStorage" | "cookies" /** Added in v1.1.0 */;
};
```**Example**
```typescript
export const useMyStore = create()(
persistNSync(
set => ({
count: 0,
_count: 0 /** skipped as it is included in exclude array */,
setCount: count => {
set(state => ({ ...state, count }));
},
set_Count: _count => {
set(state => ({ ...state, _count }));
},
}),
{ name: "example", exclude: ["_count"] },
),
);
```> It is good to note here that each element of `include` and `exclude` array can either be a string or a regular expression.
> To use regular expression, you should either use `new RegExp()` or `/your-expression/` syntax. Double or single quoted strings are not treated as regular expression.
> You can specify whether to use either `"localStorage"`, `"sessionStorage"`, or `"cookies"` to persist the state - default `"localStorage"`. Please note that `"sessionStorage"` is not persisted. Hence can be used for sync only scenarios.### Updating options at runtime
Since version 1.2, you can also update the options at runTime by setting `__persistNSyncOptions` in your Zustand state.
**Example**
```ts
interface StoreWithOptions {
count: number;
_count: number;
__persistNSyncOptions: PersistNSyncOptionsType;
setCount: (c: number) => void;
set_Count: (c: number) => void;
setOptions: (__persistNSyncOptions: PersistNSyncOptionsType) => void;
}const defaultOptions = { name: "example", include: [/count/], exclude: [/^_/] };
export const useStoreWithOptions = create(
persistNSync(
set => ({
count: 0,
_count: 0 /** skipped as it matches the regexp provided */,
__persistNSyncOptions: defaultOptions,
setCount: count => set(state => ({ ...state, count })),
set_Count: _count => set(state => ({ ...state, _count })),
setOptions: __persistNSyncOptions => set(state => ({ ...state, __persistNSyncOptions })),
}),
defaultOptions,
),
);
```### Clear Storage
Starting from version 1.2, you can also clear the persisted data by calling `clearStorage` function. It takes `name` of your store (`name` passed in `options` while creating the store), and optional `storageType` parameters.
```ts
import { clearStorage } from "persist-and-sync";...
clearStorage("my-store", "cookies");
...
```## Legacy / Deprecated
#### Ignore/filter out fields based on regExp
In several cases, you might want to exclude several fields from syncing. To support this scenario, we provide a mechanism to exclude fields based on regExp. Just pass `regExpToIgnore` (optional - default -> undefined) in the options object.
```ts
// to ignore fields containing a slug
persistNSync(
set => ({
count: 0,
slugSomeState: 1,
slugSomeState2: 1,
set: n => set({ count: n }),
}),
{ name: "my-channel", regExpToIgnore: /slug/ },
// or regExpToIgnore: new RegExp('slug')
// Use full power of regExp by adding `i` and `g` flags
),
```For more details about regExp check out - [JS RegExp](https://www.w3schools.com/jsref/jsref_obj_regexp.asp)
### Exact match
For exactly matching a parameter/field use `/^your-field-name$/`. `^` forces match from the first character and similarly, `$` forces match until the last character.
### Ignore multiple fields with exact match
use `regExpToIgnore: /^(field1|field2|field3)$/`
### 🤩 Don't forget to star [this repo](https://github.com/mayank1513/persist-and-sync)!
Want a hands-on course for getting started with Turborepo? Check out [React and Next.js with TypeScript](https://mayank-chaudhari.vercel.app/courses/react-and-next-js-with-typescript) and [The Game of Chess with Next.js, React and TypeScrypt](https://www.udemy.com/course/game-of-chess-with-nextjs-react-and-typescrypt/?referralCode=851A28F10B254A8523FE)
## License
Licensed as MIT open source.
with 💖 by Mayank Kumar Chaudhari