diff --git a/README.md b/README.md index 082bdb44..2596ffe4 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ I've developed fantastic libraries leveraging React18 features using Zustand, an As a solution, I set out to create a lightweight, bare minimum store that facilitates shared state even when importing components from separate files, optimizing tree-shaking. +> If you need fully featured state management solution, consider using Zustand with [`treeshakable`](https://github.com/react18-tools/treeshakable/) +> To understand the issue with treeshakability and importing from subpath, see - + ## Features ✅ Full TypeScript Support @@ -28,6 +31,12 @@ Utilize this hook similarly to the `useState` hook. However, ensure to pass a un const [state, setState] = useRGS("counter", 1); ``` +**_or_** + +```tsx +const [state, setState] = useRGS("counter", () => 1); +``` + > For detailed instructions, see [Getting Started](./md-docs/1.getting-started.md) ## Using Plugins diff --git a/SECURITY.md b/SECURITY.md index 175e3b69..a58834a4 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,9 +6,9 @@ We provide support for the latest minor version. Pull requests aimed at fixing s | Version | Support Status | | ------- | ------------------ | -| 1.0.x | :white_check_mark: | -| 0.2.x | :warning: | -| < 0.2 | :x: | +| 1.1.x | :white_check_mark: | +| 1.0.x | :warning: | +| < 1.0 | :x: | ## Patching Long-Term Support (LTS) Versions diff --git a/examples/nextjs/CHANGELOG.md b/examples/nextjs/CHANGELOG.md index d13f0b61..ca71a5d4 100644 --- a/examples/nextjs/CHANGELOG.md +++ b/examples/nextjs/CHANGELOG.md @@ -1,5 +1,13 @@ # nextjs-example +## 0.0.15 + +### Patch Changes + +- Updated dependencies + - r18gs@1.1.0 + - shared-ui@0.0.0 + ## 0.0.14 ### Patch Changes diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index b10f187e..8972713e 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "nextjs-example", - "version": "0.0.14", + "version": "0.0.15", "private": true, "scripts": { "dev": "next dev", diff --git a/examples/remix/CHANGELOG.md b/examples/remix/CHANGELOG.md index 4d18409d..dee4474e 100644 --- a/examples/remix/CHANGELOG.md +++ b/examples/remix/CHANGELOG.md @@ -1,5 +1,13 @@ # remix-example +## 0.0.15 + +### Patch Changes + +- Updated dependencies + - r18gs@1.1.0 + - shared-ui@0.0.0 + ## 0.0.14 ### Patch Changes diff --git a/examples/remix/package.json b/examples/remix/package.json index 32f41b52..6556c5e2 100644 --- a/examples/remix/package.json +++ b/examples/remix/package.json @@ -1,6 +1,6 @@ { "name": "remix-example", - "version": "0.0.14", + "version": "0.0.15", "private": true, "sideEffects": false, "type": "module", diff --git a/examples/vite/CHANGELOG.md b/examples/vite/CHANGELOG.md index 7f906995..2466ea0f 100644 --- a/examples/vite/CHANGELOG.md +++ b/examples/vite/CHANGELOG.md @@ -1,5 +1,13 @@ # vite-example +## 0.0.15 + +### Patch Changes + +- Updated dependencies + - r18gs@1.1.0 + - shared-ui@0.0.0 + ## 0.0.14 ### Patch Changes diff --git a/examples/vite/package.json b/examples/vite/package.json index fa1557fa..ec184200 100644 --- a/examples/vite/package.json +++ b/examples/vite/package.json @@ -1,7 +1,7 @@ { "name": "vite-example", "private": true, - "version": "0.0.14", + "version": "0.0.15", "type": "module", "scripts": { "dev": "vite --port 3001", diff --git a/lib/r18gs/CHANGELOG.md b/lib/r18gs/CHANGELOG.md index 61ee3d53..10266bfe 100644 --- a/lib/r18gs/CHANGELOG.md +++ b/lib/r18gs/CHANGELOG.md @@ -1,5 +1,11 @@ # r18gs +## 1.1.0 + +### Minor Changes + +- Support initializer function. Now you can initialize the RGStore by supplying a function in place of constant. + ## 1.0.2 ### Patch Changes diff --git a/lib/r18gs/package.json b/lib/r18gs/package.json index 79b69cf6..5df83976 100644 --- a/lib/r18gs/package.json +++ b/lib/r18gs/package.json @@ -2,7 +2,7 @@ "name": "r18gs", "author": "Mayank Kumar Chaudhari ", "private": false, - "version": "1.0.2", + "version": "1.1.0", "description": "A simple yet elegant, light weight, react18 global store to replace Zustand for better tree shaking.", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/lib/r18gs/src/index.ts b/lib/r18gs/src/index.ts index 4fde6077..17e6947e 100644 --- a/lib/r18gs/src/index.ts +++ b/lib/r18gs/src/index.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/non-nullable-type-assertion-style -- as ! operator is forbidden by eslint*/ import { createHook, createSetter, createSubcriber, globalRGS } from "./utils"; -import type { SetStateAction } from "./utils"; +import type { SetStateAction, ValueType } from "./utils"; export type { SetterArgType, SetStateAction, Plugin } from "./utils"; @@ -20,9 +20,15 @@ export type { SetterArgType, SetStateAction, Plugin } from "./utils"; * @param value - Initial value of the store. * @returns - A tuple (Ordered sequance of values) containing the state and a function to set the state. */ -const useRGS = (key: string, value?: T): [T, SetStateAction] => { +const useRGS = (key: string, value?: ValueType): [T, SetStateAction] => { /** Initialize the named store when invoked for the first time. */ - if (!globalRGS[key]) globalRGS[key] = [value, [], createSetter(key), createSubcriber(key)]; + if (!globalRGS[key]) + globalRGS[key] = [ + value instanceof Function ? value() : value, + [], + createSetter(key), + createSubcriber(key), + ]; return createHook(key); }; diff --git a/lib/r18gs/src/utils.ts b/lib/r18gs/src/utils.ts index 68003da7..421ec4ab 100644 --- a/lib/r18gs/src/utils.ts +++ b/lib/r18gs/src/utils.ts @@ -5,6 +5,7 @@ type Subscriber = (l: Listener) => () => void; export type SetterArgType = T | ((prevState: T) => T); export type SetStateAction = (value: SetterArgType) => void; +export type ValueType = T | (() => T); /** * This is a hack to reduce lib size + readability + not encouraging direct access to globalThis @@ -80,10 +81,11 @@ const initPlugins = async (key: string, plugins: Plugin[]) => { /** Initialize the named store when invoked for the first time. */ export const initWithPlugins = ( key: string, - value?: T, + value?: ValueType, plugins: Plugin[] = [], doNotInit = false, ) => { + value = value instanceof Function ? value() : value; if (doNotInit) { /** You will not have access to the setter until initialized */ globalRGS[key] = [value, [], null, createSubcriber(key)]; @@ -126,7 +128,7 @@ export const initWithPlugins = ( */ export const useRGSWithPlugins = ( key: string, - value?: T, + value?: ValueType, plugins?: Plugin[], doNotInit = false, ): [T, SetStateAction] => { diff --git a/md-docs/1.getting-started.md b/md-docs/1.getting-started.md index e1d28c0d..e951f864 100644 --- a/md-docs/1.getting-started.md +++ b/md-docs/1.getting-started.md @@ -34,6 +34,16 @@ You can access the same state across all client-side components using a unique k > It's advisable to store your keys in a separate file to prevent typos and unnecessary conflicts. +### Initializing the state with a function + +In some cases you might want to initialize the state with a function, for example, when reading from `localStorage`. We support initializer function as well. + +```tsx +const [state, setState] = useRGS("counter", () => + typeof localStorage === "undefined" ? 1 : localStorage.getItem("counter") ?? 1, +); +``` + ### Example ```tsx