Skip to content
This repository has been archived by the owner on Nov 23, 2020. It is now read-only.

[new package] @reffect/strict #8

Merged
merged 4 commits into from
May 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/react/.size-limit.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
{
"path": "reffect-react.es.js",
"webpack": false,
"limit": "300 B"
"limit": "335 B"
},
{
"path": "reffect-react.cjs.js",
"webpack": false,
"limit": "350 B"
"limit": "355 B"
},
{
"path": "reffect-react.umd.js",
"webpack": false,
"limit": "450 B"
"limit": "455 B"
}
]
6 changes: 6 additions & 0 deletions packages/react/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 1.1.3

### Fix:

1. update hooks states only if hook is mounted

# 1.1.2

### Minor:
Expand Down
2 changes: 1 addition & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@reffect/react",
"version": "1.1.2",
"version": "1.1.3",
"description": "React bindings for Reffect",
"scripts": {
"build": "node ../../build/build.js",
Expand Down
9 changes: 8 additions & 1 deletion packages/react/src/useEffectState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect";
export const useEffectState = <Effect extends EffectManagingType>(effect: Effect) => {
const [state, setState] = useState<EffectState>(null);

useIsomorphicLayoutEffect(() => manage(effect).subscribe(state => setState(state)), []);
useIsomorphicLayoutEffect(() => {
let isMount = true;
const unsubscribe = manage(effect).subscribe(state => isMount && setState(state));
return () => {
isMount = false;
unsubscribe();
};
}, []);

return {
pending: state === "pending",
Expand Down
9 changes: 8 additions & 1 deletion packages/react/src/useStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ const reducer = (state: any, newState: any) => ({ ...newState });
export const useStore = <Store extends StoreType>(store: Store): Store => {
const [state, setState] = useReducer(reducer, store);

useIsomorphicLayoutEffect(() => manage(store).subscribe(() => setState(store)), []);
useIsomorphicLayoutEffect(() => {
let isMount = true;
const unsubscribe = manage(store).subscribe(() => isMount && setState(store));
return () => {
isMount = false;
unsubscribe();
};
}, []);

return state;
};
4 changes: 4 additions & 0 deletions packages/strict/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
reffect-strict.*.js
reffect-strict.d.ts
reffect-strict.*.js.map
package-lock.json
17 changes: 17 additions & 0 deletions packages/strict/.size-limit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[
{
"path": "reffect-strict.es.js",
"webpack": false,
"limit": "310 B"
},
{
"path": "reffect-strict.cjs.js",
"webpack": false,
"limit": "340 B"
},
{
"path": "reffect-strict.umd.js",
"webpack": false,
"limit": "450 B"
}
]
3 changes: 3 additions & 0 deletions packages/strict/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 0.0.1

Created project
29 changes: 29 additions & 0 deletions packages/strict/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<div align="center">

[![reffect logo](https://raw.githubusercontent.com/acacode/reffect/master/assets/reffect.png)](https://github.com/acacode/reffect)
[![npm](https://img.shields.io/npm/v/@reffect/logger?style=flat-square&color=blue)](https://www.npmjs.com/package/@reffect/logger)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@reffect/logger?style=flat-square&color=blue)](https://bundlephobia.com/result?p=@reffect/logger)
[![license](https://img.shields.io/github/license/acacode/reffect?style=flat-square&color=blue)](https://github.com/acacode/reffect)

<div align="left">

Reffect — is a declarative and reactive multi-store state manager for JavaScript/TypeScript applications inspired by [Reatom](https://github.com/artalar/reatom) and [Effector](https://github.com/zerobias/effector)

# @reffect/strict

Store middleware for [`Reffect`](https://github.com/acacode/reffect)

## How to use

```ts
import { store, effect } from "@reffect/core";
import { strictUpdate } from "@reffect/logger";

const projectsStore = store({ projects: [] }, "projects", [strictUpdate]);

const setProjects = effect(projectsStore, "projects");
// ...

setProjects(["foo", "bar"]); // state of projectsStore will update to { projects: ["foo", "bar"] }
setProjects(["foo", "bar"]); // state of projectsStore won't update because new state and current are equals
```
48 changes: 48 additions & 0 deletions packages/strict/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@reffect/strict",
"version": "0.0.1",
"description": "strict update store middleware for Reffect",
"scripts": {
"build": "node ../../build/build.js",
"size": "size-limit"
},
"author": "acacode",
"license": "MIT",
"readme": "README.md",
"private": false,
"sideEffects": false,
"main": "reffect-strict.cjs.js",
"typings": "reffect-strict.d.ts",
"umd:main": "reffect-strict.umd.js",
"jsnext:main": "reffect-strict.es.js",
"module": "reffect-strict.es.js",
"peerDependencies": { "@reffect/core": "^1.5.0" },
"devDependencies": {
"@reffect/core": "^1.5.0",
"@size-limit/preset-small-lib": "^4.2.1",
"size-limit": "^4.2.1"
},
"files": [
"LICENSE",
"reffect-strict.d.ts",
"reffect-strict.cjs.js",
"reffect-strict.cjs.js.map",
"reffect-strict.es.js",
"reffect-strict.es.js.map",
"reffect-strict.umd.js",
"reffect-strict.umd.js.map"
],
"keywords": [
"redux",
"effector",
"mobx",
"state",
"store",
"flux",
"reactive",
"state-manager",
"state manager",
"reffect"
],
"gitHead": "a724ce9d6d802cf83fec609ad4664172a4694471"
}
29 changes: 29 additions & 0 deletions packages/strict/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { StoreType, manage } from "@reffect/core";

const equals = (obj1: object, obj2: object): obj1 is typeof obj2 => {
if (obj1 === obj2) return true;
if (!(obj1 instanceof Object) || !(obj2 instanceof Object)) return false;
if (obj1.constructor !== obj2.constructor) return false;

for (const property in obj1) {
if (obj1.hasOwnProperty(property) && (!obj2.hasOwnProperty(property) || !equals(obj1[property], obj2[property])))
return false;
}

for (const property in obj2) {
if (obj2.hasOwnProperty(property) && !obj1.hasOwnProperty(property)) return false;
}
return true;
};

export const strictUpdate = <Store extends StoreType>(store: Store, copy: (obj: object) => object) => {
const storeManager = manage(store);
const originalPartialUpdate = storeManager.partialUpdate;

storeManager.partialUpdate = (storeUpdate: Partial<Store>) =>
storeUpdate &&
!equals(store, copy({ ...storeManager.state, ...storeUpdate })) &&
originalPartialUpdate(storeUpdate);

return store;
};