@t8/react-store 1.2.8 → 1.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  React app state management condensed to the essentials
4
4
 
5
- [![npm](https://img.shields.io/npm/v/@t8/react-store?labelColor=345&color=46e)](https://www.npmjs.com/package/@t8/react-store) ![Lightweight](https://img.shields.io/bundlephobia/minzip/@t8/react-store?label=minzip&labelColor=345&color=46e)
6
-
7
- **Features:** Quickest migration from local state · Familiar useState pattern · CSR/SSR without workarounds · Integrable with Immer · Quickly pluggable persistence across page reloads
5
+ **Features:** Quickest migration from local state · Single pattern for shared and local state · CSR/SSR without workarounds · Integrable with Immer · Quickly pluggable persistence across page reloads
8
6
 
9
7
  <!-- docsgen-show-start --
10
8
  ```diff
@@ -23,8 +21,6 @@ React app state management condensed to the essentials
23
21
  ```
24
22
  -- docsgen-show-end -->
25
23
 
26
- Installation: `npm i @t8/react-store`
27
-
28
24
  ## Shared state setup
29
25
 
30
26
  Moving local state to the full-fledged shared state:
@@ -177,14 +173,14 @@ A standalone store initialized outside a component can be used by the component
177
173
 
178
174
  ## Persistence across page reloads
179
175
 
180
- Replacing `new Store(data)` with `new PersistentStore(data, storageKey)` as shown below gets the store's value initially restored from and saved whenever updated to `storageKey` in `localStorage`. (Pass `{ session: true }` as the `options` parameter of `new PersistentStore(data, storageKey, options?)` to use `sessionStorage` instead of `localStorage`.) Otherwise, persistent stores work pretty much like regular stores described above.
176
+ Replacing `new Store(data)` with `new PersistentStore(data, { key })` as shown below gets the store's value initially restored from and saved whenever updated to the specified `key` in `localStorage`. (Pass `session: true` to the second parameter of the constructor to use `sessionStorage` instead of `localStorage`.) Otherwise, persistent stores work pretty much like regular stores described above.
181
177
 
182
178
  ```js
183
- import { PersistentStore } from "@t8/react-store";
179
+ import { PersistentStore } from "@t8/persistent-store";
184
180
 
185
- let counterStore = new PersistentStore(0, "counter");
181
+ let counterStore = new PersistentStore(0, { key: "counter" });
186
182
  ```
187
183
 
188
- ⬥ The way data gets saved to and restored from a browser storage entry (including filtering out certain data or otherwise rearranging the saved data) can be redefined by setting `options.serialize` and `options.deserialize` in `new PersistentStore(data, storageKey, options?)`. By default, these options act like `JSON.stringify()` and `JSON.parse()` respectively.
184
+ ⬥ The way data gets saved to and restored from a browser storage entry (including filtering out certain data or otherwise rearranging the saved data) can be redefined by setting `options.serialize` and `options.deserialize` in `new PersistentStore(data, options)`. By default, these options act like `JSON.stringify()` and `JSON.parse()` respectively.
189
185
 
190
186
  ⬥ `PersistentStore` skips interaction with the browser storage in non-browser environments, which makes it equally usable with SSR.
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- let __t8_store = require("@t8/store");
1
+ let _t8_store = require("@t8/store");
2
2
  let react = require("react");
3
3
 
4
4
  /**
@@ -29,16 +29,16 @@ let react = require("react");
29
29
  * when this function returns `true`.
30
30
  */
31
31
  function useStore(store, shouldUpdate = true) {
32
- if (!(0, __t8_store.isStore)(store)) throw new Error("'store' is not an instance of Store");
32
+ if (!(0, _t8_store.isStore)(store)) throw new Error("'store' is not an instance of Store");
33
33
  let [, setRevision] = (0, react.useState)(-1);
34
34
  let value = store.getValue();
35
35
  let setValue = (0, react.useMemo)(() => store.setValue.bind(store), [store]);
36
36
  let initialStoreRevision = (0, react.useRef)(store.revision);
37
37
  (0, react.useEffect)(() => {
38
- if ((0, __t8_store.isPersistentStore)(store)) store.syncOnce();
38
+ store.emit("effect");
39
39
  if (!shouldUpdate) return;
40
- let unsubscribe = store.onUpdate((nextValue, prevValue) => {
41
- if (typeof shouldUpdate !== "function" || shouldUpdate(nextValue, prevValue)) setRevision(Math.random());
40
+ let unsubscribe = store.on("update", ({ current, previous }) => {
41
+ if (typeof shouldUpdate !== "function" || shouldUpdate(current, previous)) setRevision(Math.random());
42
42
  });
43
43
  if (store.revision !== initialStoreRevision.current) setRevision(Math.random());
44
44
  return () => {
@@ -50,9 +50,9 @@ function useStore(store, shouldUpdate = true) {
50
50
  }
51
51
 
52
52
  exports.useStore = useStore;
53
- Object.keys(__t8_store).forEach(function (k) {
53
+ Object.keys(_t8_store).forEach(function (k) {
54
54
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
55
55
  enumerable: true,
56
- get: function () { return __t8_store[k]; }
56
+ get: function () { return _t8_store[k]; }
57
57
  });
58
58
  });
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { isPersistentStore, isStore } from "@t8/store";
1
+ import { isStore } from "@t8/store";
2
2
  import { useEffect, useMemo, useRef, useState } from "react";
3
3
 
4
4
  export * from "@t8/store"
@@ -37,10 +37,10 @@ function useStore(store, shouldUpdate = true) {
37
37
  let setValue = useMemo(() => store.setValue.bind(store), [store]);
38
38
  let initialStoreRevision = useRef(store.revision);
39
39
  useEffect(() => {
40
- if (isPersistentStore(store)) store.syncOnce();
40
+ store.emit("effect");
41
41
  if (!shouldUpdate) return;
42
- let unsubscribe = store.onUpdate((nextValue, prevValue) => {
43
- if (typeof shouldUpdate !== "function" || shouldUpdate(nextValue, prevValue)) setRevision(Math.random());
42
+ let unsubscribe = store.on("update", ({ current, previous }) => {
43
+ if (typeof shouldUpdate !== "function" || shouldUpdate(current, previous)) setRevision(Math.random());
44
44
  });
45
45
  if (store.revision !== initialStoreRevision.current) setRevision(Math.random());
46
46
  return () => {
package/package.json CHANGED
@@ -1,45 +1,45 @@
1
- {
2
- "name": "@t8/react-store",
3
- "version": "1.2.8",
4
- "description": "React app state management condensed to the essentials",
5
- "main": "./dist/index.cjs",
6
- "module": "./dist/index.mjs",
7
- "types": "./dist/index.d.ts",
8
- "type": "module",
9
- "scripts": {
10
- "demo": "npx @t8/serve tests/counter --spa -b src/index.tsx",
11
- "demo-t3": "npx @t8/serve tests/tic-tac-toe --spa -b src/index.tsx",
12
- "preversion": "npx npm-run-all shape test",
13
- "shape": "npx codeshape",
14
- "test": "npx playwright test --project=chromium"
15
- },
16
- "repository": {
17
- "type": "git",
18
- "url": "git+https://github.com/t8js/react-store.git"
19
- },
20
- "homepage": "https://t8.js.org/react-store",
21
- "keywords": [
22
- "react",
23
- "state management",
24
- "shared state",
25
- "global state",
26
- "store"
27
- ],
28
- "author": "axtk",
29
- "license": "MIT",
30
- "peerDependencies": {
31
- "react": ">=16.8"
32
- },
33
- "devDependencies": {
34
- "@playwright/test": "^1.56.0",
35
- "@t8/serve": "^0.2.0",
36
- "@types/node": "^24.5.2",
37
- "@types/react": "^19.2.7",
38
- "@types/react-dom": "^19.2.3",
39
- "immer": "^11.0.1",
40
- "react-dom": "^19.2.3"
41
- },
42
- "dependencies": {
43
- "@t8/store": "^1.4.0"
44
- }
45
- }
1
+ {
2
+ "name": "@t8/react-store",
3
+ "version": "1.2.10",
4
+ "description": "React app state management condensed to the essentials",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "type": "module",
9
+ "scripts": {
10
+ "demo": "npx @t8/serve tests/counter --spa -b src/index.tsx",
11
+ "demo-t3": "npx @t8/serve tests/tic-tac-toe --spa -b src/index.tsx",
12
+ "preversion": "npx npm-run-all shape test",
13
+ "shape": "npx codeshape",
14
+ "test": "npx playwright test --project=chromium"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/t8js/react-store.git"
19
+ },
20
+ "homepage": "https://t8.js.org/react-store",
21
+ "keywords": [
22
+ "react",
23
+ "state management",
24
+ "shared state",
25
+ "global state",
26
+ "store"
27
+ ],
28
+ "author": "axtk",
29
+ "license": "MIT",
30
+ "peerDependencies": {
31
+ "react": ">=16.8"
32
+ },
33
+ "devDependencies": {
34
+ "@playwright/test": "^1.56.0",
35
+ "@t8/serve": "^0.2.0",
36
+ "@types/node": "^24.5.2",
37
+ "@types/react": "^19.2.9",
38
+ "@types/react-dom": "^19.2.3",
39
+ "immer": "^11.1.3",
40
+ "react-dom": "^19.2.3"
41
+ },
42
+ "dependencies": {
43
+ "@t8/store": "^1.5.0"
44
+ }
45
+ }
package/src/useStore.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { isPersistentStore, isStore, type Store } from "@t8/store";
1
+ import { isStore, type Store } from "@t8/store";
2
2
  import { useEffect, useMemo, useRef, useState } from "react";
3
3
 
4
4
  export type SetStoreValue<T> = Store<T>["setValue"];
@@ -46,15 +46,13 @@ export function useStore<T>(
46
46
  let initialStoreRevision = useRef(store.revision);
47
47
 
48
48
  useEffect(() => {
49
- if (isPersistentStore<T>(store)) store.syncOnce();
49
+ // Allow stores to hook into the effect
50
+ store.emit("effect");
50
51
 
51
52
  if (!shouldUpdate) return;
52
53
 
53
- let unsubscribe = store.onUpdate((nextValue, prevValue) => {
54
- if (
55
- typeof shouldUpdate !== "function" ||
56
- shouldUpdate(nextValue, prevValue)
57
- )
54
+ let unsubscribe = store.on("update", ({ current, previous }) => {
55
+ if (typeof shouldUpdate !== "function" || shouldUpdate(current, previous))
58
56
  setRevision(Math.random());
59
57
  });
60
58