Skip to content

Commit

Permalink
Allow 3th party libraries to expand Teaful with extras (#50)
Browse files Browse the repository at this point in the history
* Add extras

* Modify mangle

* Reduce bits

* Reduce bits
  • Loading branch information
aralroca authored Nov 24, 2021
1 parent a3e2cbc commit bc6a297
Show file tree
Hide file tree
Showing 5 changed files with 423 additions and 616 deletions.
21 changes: 21 additions & 0 deletions mangle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"minify": {
"mangle": {
"properties": {
"regex": "^_"
}
},
"compress": {
"hoist_vars": true,
"reduce_funcs": true
}
},
"props": {
"cname": 6,
"props": {
"$_subscribe": "s",
"$_notify": "n",
"$_unsubscribe": "u"
}
}
}
29 changes: 13 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "teaful",
"version": "0.8.0",
"version": "0.9.0-canary.1",
"description": "Tiny, easy and powerful React state management (less than 1kb)",
"license": "MIT",
"keywords": [
Expand Down Expand Up @@ -75,27 +75,24 @@
},
"devDependencies": {
"@babel/polyfill": "7.12.1",
"@babel/preset-env": "7.15.8",
"@babel/preset-react": "7.14.5",
"@testing-library/dom": "8.9.1",
"@babel/preset-env": "7.16.4",
"@babel/preset-react": "7.16.0",
"@testing-library/dom": "8.11.1",
"@testing-library/react": "12.1.2",
"@testing-library/user-event": "13.4.1",
"babel-jest": "27.2.5",
"@testing-library/user-event": "13.5.0",
"babel-jest": "27.3.1",
"bundlewatch": "0.3.2",
"eslint": "7.32.0",
"eslint": "8.3.0",
"eslint-config-google": "0.14.0",
"eslint-plugin-jest": "25.2.2",
"eslint-plugin-react": "7.26.1",
"eslint-plugin-react-hooks": "4.2.0",
"eslint-plugin-testing-library": "4.12.4",
"jest": "27.2.5",
"microbundle": "0.14.1",
"eslint-plugin-jest": "25.3.0",
"eslint-plugin-react": "7.27.1",
"eslint-plugin-react-hooks": "4.3.0",
"eslint-plugin-testing-library": "5.0.0",
"jest": "27.3.1",
"microbundle": "0.14.2",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-test-renderer": "17.0.2"
},
"mangle": {
"regex": "^_"
},
"bugs": "https://github.com/teafuljs/teaful/issues"
}
18 changes: 15 additions & 3 deletions package/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ let MODE_GET = 1;
let MODE_USE = 2;
let MODE_WITH = 3;
let DOT = '.';
let extras = [];

export default function createStore(defaultStore = {}, callback) {
let subscription = createSubscription();
Expand All @@ -23,7 +24,7 @@ export default function createStore(defaultStore = {}, callback) {
let validator = {
_path: [],
_getHoC(Comp, path, initValue, callback) {
let componentName = Comp.displayName || Comp.name || 'Component';
let componentName = Comp.displayName || Comp.name || '';
let WithStore = (props) => {
let last = path.length - 1;
let store = path.length ? path.reduce(
Expand Down Expand Up @@ -100,7 +101,7 @@ export default function createStore(defaultStore = {}, callback) {
* @param {function} callback
*/
function useSubscription(path, callback) {
let forceRender = useReducer(() => ({}), 0)[1];
let forceRender = useReducer(() => [], 0)[1];

useEffect(() => {
subscription._subscribe(path, forceRender);
Expand Down Expand Up @@ -161,32 +162,43 @@ export default function createStore(defaultStore = {}, callback) {
});
}

let result = extras.reduce((res, fn) => {
let newRes = fn(res, subscription);
return typeof newRes === 'object' ? {...res, ...newRes} : res;
}, {useStore, getStore, withStore});

/**
* createStore function returns:
* - useStore hook
* - getStore helper
* - withStore HoC
* - extras that 3rd party can add
* @returns {object}
*/
return {useStore, getStore, withStore};
return result;
}

createStore.ext = (extra) => typeof extra === 'function' && extras.push(extra);

function createSubscription() {
let listeners = {};

return {
// Renamed to "s" after build to minify code
_subscribe(path, listener) {
if (typeof listener !== 'function') return;
if (!listeners[path]) listeners[path] = new Set();
listeners[path].add(listener);
},
// Renamed to "n" after build to minify code
_notify(path, params) {
Object.keys(listeners).forEach((listenerKey) => {
if (path.startsWith(listenerKey) || listenerKey.startsWith(path)) {
listeners[listenerKey].forEach((listener) => listener(params));
}
});
},
// Renamed to "u" after build to minify code
_unsubscribe(path, listener) {
if (typeof listener !== 'function') return;
listeners[path].delete(listener);
Expand Down
34 changes: 34 additions & 0 deletions tests/extras.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import '@babel/polyfill';

import createStore from '../package/index';

describe('Extras', () => {
it('should be possible to register a library extra',
async () => {
createStore.ext(({getStore}, subscription) => {
const [, setTest2] = getStore.test2();
// Renamed to "subscription.s()" after build to minify code
subscription._subscribe('.', ({store}) => {
if (store.test === 3 && !store.test2) {
setTest2(4);
}
});
return {getStoreFromPath: (path) => getStore[path]()};
});

const {getStoreFromPath} = createStore({test: 0, test2: 0});

const [, setTest] = getStoreFromPath('test');
setTest(1);
expect(getStoreFromPath('test')[0]).toBe(1);
expect(getStoreFromPath('test2')[0]).toBe(0);

setTest(2);
expect(getStoreFromPath('test')[0]).toBe(2);
expect(getStoreFromPath('test2')[0]).toBe(0);

setTest(3);
expect(getStoreFromPath('test')[0]).toBe(3);
expect(getStoreFromPath('test2')[0]).toBe(4);
});
});
Loading

0 comments on commit bc6a297

Please sign in to comment.