react-use-sub
Advanced tools
Comparing version 0.4.0 to 0.5.0
@@ -8,93 +8,74 @@ 'use strict'; | ||
const _enqueue = fn => window.setTimeout(fn, 0); | ||
const _type = a => Object.prototype.toString.call(a); | ||
const _enqueue = (fn) => window.setTimeout(fn, 0); | ||
const _type = (a) => Object.prototype.toString.call(a); | ||
const _diffArr = (a, b) => a.length !== b.length || a.some((v, i) => b[i] !== v); | ||
const _diff = (a, b) => { | ||
if (a === b) return false; | ||
const aType = _type(a); | ||
if (aType !== _type(b)) return true; | ||
if (aType === '[object Array]') return _diffArr(a, b); | ||
if (aType === '[object Object]') return Object.keys(a).concat(Object.keys(b)).some(i => b[i] !== a[i]); | ||
return true; | ||
if (a === b) | ||
return false; | ||
const aType = _type(a); | ||
if (aType !== _type(b)) | ||
return true; | ||
if (aType === '[object Array]') | ||
return _diffArr(a, b); | ||
if (aType === '[object Object]') | ||
return Object.keys(a) | ||
.concat(Object.keys(b)) | ||
.some((i) => b[i] !== a[i]); | ||
return true; | ||
}; | ||
const _dispatch = D => reactDom.unstable_batchedUpdates(() => { | ||
D.subs.forEach(({ | ||
mapper, | ||
update, | ||
last | ||
}) => { | ||
const nowMapped = mapper(D.data); | ||
if (_diff(nowMapped, last)) { | ||
update(nowMapped); | ||
} | ||
}); | ||
const _dispatch = (D) => reactDom.unstable_batchedUpdates(() => { | ||
D.subs.forEach(({ mapper, update, last }) => { | ||
const nowMapped = mapper(D.data); | ||
if (_diff(nowMapped, last)) { | ||
update(nowMapped); | ||
} | ||
}); | ||
}); | ||
const _update = (D, next) => { | ||
const result = {}; | ||
D.keys.forEach(key => { | ||
const p = D.data[key]; | ||
const n = next[key]; | ||
result[key] = n !== undefined ? n : p; | ||
}); | ||
D.data = result; | ||
const result = {}; | ||
D.keys.forEach(key => { | ||
const p = D.data[key]; | ||
const n = next[key]; | ||
result[key] = n !== undefined ? n : p; | ||
}); | ||
D.data = result; | ||
}; | ||
const _center = D => ({ | ||
get: () => D.data, | ||
set: update => { | ||
const next = typeof update === 'function' ? update(D.data) : update; | ||
_update(D, next); | ||
_enqueue(() => _dispatch(D)); | ||
} | ||
const _center = (D) => ({ | ||
get: () => D.data, | ||
set: (update) => { | ||
const next = typeof update === 'function' ? update(D.data) : update; | ||
_update(D, next); | ||
_enqueue(() => _dispatch(D)); | ||
}, | ||
}); | ||
const _emptyDeps = []; | ||
const createStore = data => { | ||
const keys = Object.keys(data); | ||
const D = { | ||
data, | ||
subs: new Set(), | ||
keys | ||
}; | ||
const Store = _center(D); | ||
const useSub = (mapper, deps = _emptyDeps) => { | ||
const lastDeps = react.useRef(deps); | ||
const [mapped, update] = react.useState(() => mapper(D.data)); | ||
const sub = react.useRef({ | ||
mapper, | ||
update, | ||
last: mapped | ||
}); | ||
sub.current.last = mapped; | ||
if (_diffArr(lastDeps.current, deps)) { | ||
sub.current.mapper = mapper; | ||
sub.current.last = mapper(D.data); | ||
} | ||
lastDeps.current = deps; | ||
react.useEffect(() => { | ||
D.subs.add(sub.current); | ||
return () => { | ||
D.subs.delete(sub.current); | ||
}; | ||
}, []); | ||
return sub.current.last; | ||
}; | ||
return [useSub, Store]; | ||
const createStore = (data) => { | ||
const keys = Object.keys(data); | ||
const D = { | ||
data, | ||
subs: new Set(), | ||
keys, | ||
}; | ||
const Store = _center(D); | ||
const useSub = (mapper, deps = _emptyDeps) => { | ||
const lastDeps = react.useRef(deps); | ||
const [mapped, update] = react.useState(() => mapper(D.data)); | ||
const sub = react.useRef({ mapper, update, last: mapped }); | ||
sub.current.last = mapped; | ||
if (_diffArr(lastDeps.current, deps)) { | ||
sub.current.mapper = mapper; | ||
sub.current.last = mapper(D.data); | ||
} | ||
lastDeps.current = deps; | ||
react.useEffect(() => { | ||
D.subs.add(sub.current); | ||
return () => { | ||
D.subs.delete(sub.current); // eslint-disable-line | ||
}; | ||
}, []); // eslint-disable-line | ||
return sub.current.last; | ||
}; | ||
return [useSub, Store]; | ||
}; | ||
exports.createStore = createStore; |
import { useRef, useState, useEffect } from 'react'; | ||
import { unstable_batchedUpdates } from 'react-dom'; | ||
const _enqueue = fn => window.setTimeout(fn, 0); | ||
const _type = a => Object.prototype.toString.call(a); | ||
const _enqueue = (fn) => window.setTimeout(fn, 0); | ||
const _type = (a) => Object.prototype.toString.call(a); | ||
const _diffArr = (a, b) => a.length !== b.length || a.some((v, i) => b[i] !== v); | ||
const _diff = (a, b) => { | ||
if (a === b) return false; | ||
const aType = _type(a); | ||
if (aType !== _type(b)) return true; | ||
if (aType === '[object Array]') return _diffArr(a, b); | ||
if (aType === '[object Object]') return Object.keys(a).concat(Object.keys(b)).some(i => b[i] !== a[i]); | ||
return true; | ||
if (a === b) | ||
return false; | ||
const aType = _type(a); | ||
if (aType !== _type(b)) | ||
return true; | ||
if (aType === '[object Array]') | ||
return _diffArr(a, b); | ||
if (aType === '[object Object]') | ||
return Object.keys(a) | ||
.concat(Object.keys(b)) | ||
.some((i) => b[i] !== a[i]); | ||
return true; | ||
}; | ||
const _dispatch = D => unstable_batchedUpdates(() => { | ||
D.subs.forEach(({ | ||
mapper, | ||
update, | ||
last | ||
}) => { | ||
const nowMapped = mapper(D.data); | ||
if (_diff(nowMapped, last)) { | ||
update(nowMapped); | ||
} | ||
}); | ||
const _dispatch = (D) => unstable_batchedUpdates(() => { | ||
D.subs.forEach(({ mapper, update, last }) => { | ||
const nowMapped = mapper(D.data); | ||
if (_diff(nowMapped, last)) { | ||
update(nowMapped); | ||
} | ||
}); | ||
}); | ||
const _update = (D, next) => { | ||
const result = {}; | ||
D.keys.forEach(key => { | ||
const p = D.data[key]; | ||
const n = next[key]; | ||
result[key] = n !== undefined ? n : p; | ||
}); | ||
D.data = result; | ||
const result = {}; | ||
D.keys.forEach(key => { | ||
const p = D.data[key]; | ||
const n = next[key]; | ||
result[key] = n !== undefined ? n : p; | ||
}); | ||
D.data = result; | ||
}; | ||
const _center = D => ({ | ||
get: () => D.data, | ||
set: update => { | ||
const next = typeof update === 'function' ? update(D.data) : update; | ||
_update(D, next); | ||
_enqueue(() => _dispatch(D)); | ||
} | ||
const _center = (D) => ({ | ||
get: () => D.data, | ||
set: (update) => { | ||
const next = typeof update === 'function' ? update(D.data) : update; | ||
_update(D, next); | ||
_enqueue(() => _dispatch(D)); | ||
}, | ||
}); | ||
const _emptyDeps = []; | ||
const createStore = data => { | ||
const keys = Object.keys(data); | ||
const D = { | ||
data, | ||
subs: new Set(), | ||
keys | ||
}; | ||
const Store = _center(D); | ||
const useSub = (mapper, deps = _emptyDeps) => { | ||
const lastDeps = useRef(deps); | ||
const [mapped, update] = useState(() => mapper(D.data)); | ||
const sub = useRef({ | ||
mapper, | ||
update, | ||
last: mapped | ||
}); | ||
sub.current.last = mapped; | ||
if (_diffArr(lastDeps.current, deps)) { | ||
sub.current.mapper = mapper; | ||
sub.current.last = mapper(D.data); | ||
} | ||
lastDeps.current = deps; | ||
useEffect(() => { | ||
D.subs.add(sub.current); | ||
return () => { | ||
D.subs.delete(sub.current); | ||
}; | ||
}, []); | ||
return sub.current.last; | ||
}; | ||
return [useSub, Store]; | ||
const createStore = (data) => { | ||
const keys = Object.keys(data); | ||
const D = { | ||
data, | ||
subs: new Set(), | ||
keys, | ||
}; | ||
const Store = _center(D); | ||
const useSub = (mapper, deps = _emptyDeps) => { | ||
const lastDeps = useRef(deps); | ||
const [mapped, update] = useState(() => mapper(D.data)); | ||
const sub = useRef({ mapper, update, last: mapped }); | ||
sub.current.last = mapped; | ||
if (_diffArr(lastDeps.current, deps)) { | ||
sub.current.mapper = mapper; | ||
sub.current.last = mapper(D.data); | ||
} | ||
lastDeps.current = deps; | ||
useEffect(() => { | ||
D.subs.add(sub.current); | ||
return () => { | ||
D.subs.delete(sub.current); // eslint-disable-line | ||
}; | ||
}, []); // eslint-disable-line | ||
return sub.current.last; | ||
}; | ||
return [useSub, Store]; | ||
}; | ||
export { createStore }; |
{ | ||
"name": "react-use-sub", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "Subscription based lightweight React store", | ||
"main": "dist/cjs/index.js", | ||
"module": "dist/esm/index.js", | ||
"types": "src/index.d.ts", | ||
"types": "src/index.tsx", | ||
"files": [ | ||
@@ -19,3 +19,2 @@ "dist/cjs", | ||
"React", | ||
"flow", | ||
"TypeScript", | ||
@@ -29,7 +28,5 @@ "Store", | ||
"dist": "rm -rf dist && rollup -c", | ||
"eslint": "eslint --cache --cache-location 'build/.eslintcache' src/ test/", | ||
"flow": "flow --quiet", | ||
"test": "yarn flow && yarn eslint && yarn test-coverage", | ||
"test-coverage": "jest --all --coverage", | ||
"prettier": "prettier --config .prettierrc --write src/**/*.js test/**/*.js", | ||
"eslint": "eslint --cache --cache-location 'build/.eslintcache' --ext .ts,.tsx src/ test/", | ||
"test": "yarn tsc && yarn eslint && yarn test-coverage", | ||
"test-coverage": "jest --all --coverage --colors", | ||
"coveralls": "cat ./coverage/lcov.info | coveralls" | ||
@@ -43,18 +40,20 @@ }, | ||
"devDependencies": { | ||
"@babel/core": "^7.7.7", | ||
"@babel/plugin-proposal-class-properties": "^7.7.4", | ||
"@babel/preset-env": "^7.7.7", | ||
"@babel/preset-flow": "^7.7.4", | ||
"@babel/preset-react": "^7.7.4", | ||
"@babel/core": "^7.8.4", | ||
"@babel/plugin-proposal-class-properties": "^7.8.3", | ||
"@babel/preset-env": "^7.8.4", | ||
"@babel/preset-react": "^7.8.3", | ||
"@babel/preset-typescript": "^7.8.3", | ||
"@testing-library/react": "^9.4.0", | ||
"babel-eslint": "^10.0.3", | ||
"babel-jest": "^24.9.0", | ||
"@types/jest": "^25.1.1", | ||
"@types/react": "^16.9.19", | ||
"@types/react-dom": "^16.9.5", | ||
"@typescript-eslint/eslint-plugin": "^2.18.0", | ||
"@typescript-eslint/parser": "^2.18.0", | ||
"babel-jest": "^25.1.0", | ||
"coveralls": "^3.0.9", | ||
"eslint": "^6.8.0", | ||
"eslint-config-prettier": "^6.9.0", | ||
"eslint-plugin-flowtype": "^4.5.2", | ||
"eslint-config-prettier": "^6.10.0", | ||
"eslint-plugin-prettier": "^3.1.2", | ||
"eslint-plugin-react": "^7.17.0", | ||
"flow-bin": "^0.114.0", | ||
"jest": "^24.9.0", | ||
"eslint-plugin-react": "^7.18.0", | ||
"jest": "^25.1.0", | ||
"prettier": "^1.19.1", | ||
@@ -64,6 +63,7 @@ "react": "^16.12.0", | ||
"react-test-renderer": "^16.12.0", | ||
"rollup": "^1.27.14", | ||
"rollup": "^1.31.0", | ||
"rollup-plugin-babel": "^4.3.3", | ||
"rollup-plugin-flow-entry": "^0.3.3" | ||
"rollup-plugin-typescript2": "^0.25.3", | ||
"typescript": "^3.7.5" | ||
} | ||
} |
[![GitHub license][license-image]][license-url] | ||
[![npm package][npm-image]][npm-url] | ||
[![Travis][build-image]][build-url] | ||
[![Coverage Status][coveralls-image]][coveralls-url] | ||
[![styled with prettier][prettier-image]][prettier-url] | ||
@@ -13,3 +16,3 @@ | ||
- no react context | ||
- TypeScript and Flow support | ||
- TypeScript support included | ||
- Very small package size (< 1kB gzipped) | ||
@@ -23,3 +26,3 @@ - Much better performance than react-redux | ||
const initialState = { foo: 'bar' }; | ||
const initialState = { foo: 'bar', num: 2 }; | ||
export const [useSub, Store] = createStore(initialState); | ||
@@ -32,5 +35,6 @@ | ||
// subscribe here your custom store mapper | ||
const { fooLength } = useSub(({ foo }) => ({ fooLength: foo.length })); | ||
const { fooLength, num } = useSub(({ foo, num }) => ({ fooLength: foo.length, num })); | ||
const square = useSub(({ num }) => num**2); | ||
return <div>Foo has length: {fooLength}</div>; | ||
return <div>Magic number is: {fooLength * num * square}</div>; | ||
} | ||
@@ -44,3 +48,3 @@ | ||
// this updates the stored data | ||
expect(Store.get()).toEqual({ foo: 'something' }); | ||
expect(Store.get()).toEqual({ foo: 'something', num: 2 }); | ||
// and updates all components that would be passed | ||
@@ -51,4 +55,10 @@ // different values from the subscribed store mapper | ||
[license-image]: https://img.shields.io/badge/license-MIT-blue.svg | ||
[license-url]: https://github.com/fdc-viktor-luft/form4react/blob/master/LICENSE | ||
[license-url]: https://github.com/fdc-viktor-luft/react-use-sub/blob/master/LICENSE | ||
[build-image]: https://img.shields.io/travis/fdc-viktor-luft/react-use-sub/master.svg?style=flat-square | ||
[build-url]: https://travis-ci.org/fdc-viktor-luft/react-use-sub | ||
[npm-image]: https://img.shields.io/npm/v/react-use-sub.svg?style=flat-square | ||
[npm-url]: https://www.npmjs.org/package/react-use-sub | ||
[coveralls-image]: https://coveralls.io/repos/github/fdc-viktor-luft/react-use-sub/badge.svg?branch=master | ||
[coveralls-url]: https://coveralls.io/github/fdc-viktor-luft/react-use-sub?branch=master | ||
[prettier-image]: https://img.shields.io/badge/styled_with-prettier-ff69b4.svg | ||
[prettier-url]: https://github.com/prettier/prettier |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13484
60
26
6
235
1