@simplux/react
Version:
The react extension package of simplux. Provides a simple way to use simplux in react applications.
75 lines (74 loc) • 12.5 kB
JavaScript
import { _getStoreProxy, } from '@simplux/core';
import React, { createContext, useContext, useEffect, useState, } from 'react';
import { unstable_batchedUpdates } from 'react-dom';
// this default context value just passes calls through to the module; this
// is mainly useful for testing since you do not have to wrap your component
// in a provider
const defaultValue = {
subscribeToModuleStateChanges(simpluxModule, handler) {
return simpluxModule.subscribeToStateChanges(handler).unsubscribe;
},
getModuleState: (simpluxModule) => simpluxModule.$simplux.getState(),
};
// by always returning 0 for `calculateChangedBits` we prevent components
// from re-rendering just because they access the context value; instead
// it is up to each component to decide when to render, the context is just
// responsible for providing a consistent state value during each render
// pass
const SimpluxContext = createContext(defaultValue, () => 0);
// we only support accessing the context via the useSimplux hook
delete SimpluxContext.Consumer;
export const useSimpluxContext = () => useContext(SimpluxContext);
export const useSimpluxSubscription = (getStoreProxy) => {
const [moduleStates, setModuleStates] = useState(() => getStoreProxy().getState());
const subscribers = new Map();
useEffect(() => {
let previousModuleStates = moduleStates;
let currentModuleStates = moduleStates;
return getStoreProxy().subscribe(() => {
previousModuleStates = currentModuleStates;
currentModuleStates = getStoreProxy().getState();
unstable_batchedUpdates(() => {
setModuleStates(currentModuleStates);
subscribers.forEach((moduleSubscribers, moduleName) => {
const currentState = currentModuleStates[moduleName];
const prevState = previousModuleStates[moduleName];
if (currentState !== prevState) {
moduleSubscribers.forEach((sub) => sub(currentState, prevState));
}
});
});
});
}, []);
function getModuleState(simpluxModule) {
return (simpluxModule.$simplux.mockStateValue ||
moduleStates[simpluxModule.$simplux.name] ||
simpluxModule.$simplux.getState());
}
function subscribeToModuleStateChanges(simpluxModule, handler) {
const moduleName = simpluxModule.$simplux.name;
const moduleState = getModuleState(simpluxModule);
if (!subscribers.has(moduleName)) {
subscribers.set(moduleName, new Set());
}
subscribers.get(moduleName).add(handler);
handler(moduleState, moduleState);
return () => subscribers.get(moduleName).delete(handler);
}
return {
getModuleState,
subscribeToModuleStateChanges,
};
};
/**
* A provider for allowing components to use state from simplux modules.
*
* It is recommended to wrap your entire application with a single provider.
*
* @public
*/
export const SimpluxProvider = ({ children, }) => {
const contextValue = useSimpluxSubscription(_getStoreProxy);
return (React.createElement(SimpluxContext.Provider, { value: contextValue }, children));
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC5qcyIsInNvdXJjZXMiOlsiQHNpbXBsdXgvcmVhY3Qvc3JjL2NvbnRleHQudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEltbXV0YWJsZSxcbiAgU2ltcGx1eE1vZHVsZSxcbiAgU3RhdGVDaGFuZ2VIYW5kbGVyLFxuICBfZ2V0U3RvcmVQcm94eSxcbiAgX0ludGVybmFsUmVkdXhTdG9yZVByb3h5LFxufSBmcm9tICdAc2ltcGx1eC9jb3JlJ1xuaW1wb3J0IFJlYWN0LCB7XG4gIENvbnRleHQsXG4gIGNyZWF0ZUNvbnRleHQsXG4gIEZ1bmN0aW9uQ29tcG9uZW50LFxuICBSZWFjdE5vZGUsXG4gIHVzZUNvbnRleHQsXG4gIHVzZUVmZmVjdCxcbiAgdXNlU3RhdGUsXG59IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgdW5zdGFibGVfYmF0Y2hlZFVwZGF0ZXMgfSBmcm9tICdyZWFjdC1kb20nXG5cbi8vIHJlcXVpcmVkIHNpbmNlIFJlYWN0IHR5cGluZ3MgdG8gbm90IGluY2x1ZGUgdGhlIHNlY29uZCBwYXJhbWV0ZXJcbnR5cGUgQ3JlYXRlQ29udGV4dEZuID0gPFQ+KFxuICBkZWZhdWx0VmFsdWU6IFQsXG4gIGNhbGN1bGF0ZUNoYW5nZWRCaXRzOiAoKSA9PiBudW1iZXIsXG4pID0+IENvbnRleHQ8VD5cblxuZXhwb3J0IGludGVyZmFjZSBTaW1wbHV4Q29udGV4dFZhbHVlIHtcbiAgc3Vic2NyaWJlVG9Nb2R1bGVTdGF0ZUNoYW5nZXM6IDxUU3RhdGU+KFxuICAgIHNpbXBsdXhNb2R1bGU6IFNpbXBsdXhNb2R1bGU8VFN0YXRlPixcbiAgICBoYW5kbGVyOiBTdGF0ZUNoYW5nZUhhbmRsZXI8VFN0YXRlPixcbiAgKSA9PiAoKSA9PiB2b2lkXG5cbiAgZ2V0TW9kdWxlU3RhdGU6IDxUU3RhdGU+KFxuICAgIHNpbXBsdXhNb2R1bGU6IFNpbXBsdXhNb2R1bGU8VFN0YXRlPixcbiAgKSA9PiBJbW11dGFibGU8VFN0YXRlPlxufVxuXG5pbnRlcmZhY2UgTW9kdWxlU3RhdGVzIHtcbiAgW21vZHVsZU5hbWU6IHN0cmluZ106IGFueVxufVxuXG4vLyB0aGlzIGRlZmF1bHQgY29udGV4dCB2YWx1ZSBqdXN0IHBhc3NlcyBjYWxscyB0aHJvdWdoIHRvIHRoZSBtb2R1bGU7IHRoaXNcbi8vIGlzIG1haW5seSB1c2VmdWwgZm9yIHRlc3Rpbmcgc2luY2UgeW91IGRvIG5vdCBoYXZlIHRvIHdyYXAgeW91ciBjb21wb25lbnRcbi8vIGluIGEgcHJvdmlkZXJcbmNvbnN0IGRlZmF1bHRWYWx1ZTogU2ltcGx1eENvbnRleHRWYWx1ZSA9IHtcbiAgc3Vic2NyaWJlVG9Nb2R1bGVTdGF0ZUNoYW5nZXMoc2ltcGx1eE1vZHVsZSwgaGFuZGxlcikge1xuICAgIHJldHVybiBzaW1wbHV4TW9kdWxlLnN1YnNjcmliZVRvU3RhdGVDaGFuZ2VzKGhhbmRsZXIpLnVuc3Vic2NyaWJlXG4gIH0sXG4gIGdldE1vZHVsZVN0YXRlOiAoc2ltcGx1eE1vZHVsZSkgPT4gc2ltcGx1eE1vZHVsZS4kc2ltcGx1eC5nZXRTdGF0ZSgpLFxufVxuXG4vLyBieSBhbHdheXMgcmV0dXJuaW5nIDAgZm9yIGBjYWxjdWxhdGVDaGFuZ2VkQml0c2Agd2UgcHJldmVudCBjb21wb25lbnRzXG4vLyBmcm9tIHJlLXJlbmRlcmluZyBqdXN0IGJlY2F1c2UgdGhleSBhY2Nlc3MgdGhlIGNvbnRleHQgdmFsdWU7IGluc3RlYWRcbi8vIGl0IGlzIHVwIHRvIGVhY2ggY29tcG9uZW50IHRvIGRlY2lkZSB3aGVuIHRvIHJlbmRlciwgdGhlIGNvbnRleHQgaXMganVzdFxuLy8gcmVzcG9uc2libGUgZm9yIHByb3ZpZGluZyBhIGNvbnNpc3RlbnQgc3RhdGUgdmFsdWUgZHVyaW5nIGVhY2ggcmVuZGVyXG4vLyBwYXNzXG5jb25zdCBTaW1wbHV4Q29udGV4dCA9IChjcmVhdGVDb250ZXh0IGFzIENyZWF0ZUNvbnRleHRGbikoZGVmYXVsdFZhbHVlLCAoKSA9PiAwKVxuXG4vLyB3ZSBvbmx5IHN1cHBvcnQgYWNjZXNzaW5nIHRoZSBjb250ZXh0IHZpYSB0aGUgdXNlU2ltcGx1eCBob29rXG5kZWxldGUgKFNpbXBsdXhDb250ZXh0IGFzIFBhcnRpYWw8dHlwZW9mIFNpbXBsdXhDb250ZXh0PikuQ29uc3VtZXJcblxuZXhwb3J0IGNvbnN0IHVzZVNpbXBsdXhDb250ZXh0ID0gKCkgPT4gdXNlQ29udGV4dChTaW1wbHV4Q29udGV4dClcblxuZXhwb3J0IGNvbnN0IHVzZVNpbXBsdXhTdWJzY3JpcHRpb24gPSAoXG4gIGdldFN0b3JlUHJveHk6ICgpID0+IF9JbnRlcm5hbFJlZHV4U3RvcmVQcm94eSxcbik6IFNpbXBsdXhDb250ZXh0VmFsdWUgPT4ge1xuICBjb25zdCBbbW9kdWxlU3RhdGVzLCBzZXRNb2R1bGVTdGF0ZXNdID0gdXNlU3RhdGU8TW9kdWxlU3RhdGVzPigoKSA9PlxuICAgIGdldFN0b3JlUHJveHkoKS5nZXRTdGF0ZSgpLFxuICApXG5cbiAgY29uc3Qgc3Vic2NyaWJlcnMgPSBuZXcgTWFwPFxuICAgIHN0cmluZyxcbiAgICBTZXQ8KHN0YXRlOiBhbnksIHByZXZpb3VzU3RhdGU6IGFueSkgPT4gdm9pZD5cbiAgPigpXG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBsZXQgcHJldmlvdXNNb2R1bGVTdGF0ZXMgPSBtb2R1bGVTdGF0ZXNcbiAgICBsZXQgY3VycmVudE1vZHVsZVN0YXRlcyA9IG1vZHVsZVN0YXRlc1xuXG4gICAgcmV0dXJuIGdldFN0b3JlUHJveHkoKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgcHJldmlvdXNNb2R1bGVTdGF0ZXMgPSBjdXJyZW50TW9kdWxlU3RhdGVzXG4gICAgICBjdXJyZW50TW9kdWxlU3RhdGVzID0gZ2V0U3RvcmVQcm94eSgpLmdldFN0YXRlKClcblxuICAgICAgdW5zdGFibGVfYmF0Y2hlZFVwZGF0ZXMoKCkgPT4ge1xuICAgICAgICBzZXRNb2R1bGVTdGF0ZXMoY3VycmVudE1vZHVsZVN0YXRlcylcblxuICAgICAgICBzdWJzY3JpYmVycy5mb3JFYWNoKChtb2R1bGVTdWJzY3JpYmVycywgbW9kdWxlTmFtZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IGN1cnJlbnRNb2R1bGVTdGF0ZXNbbW9kdWxlTmFtZV1cbiAgICAgICAgICBjb25zdCBwcmV2U3RhdGUgPSBwcmV2aW91c01vZHVsZVN0YXRlc1ttb2R1bGVOYW1lXVxuXG4gICAgICAgICAgaWYgKGN1cnJlbnRTdGF0ZSAhPT0gcHJldlN0YXRlKSB7XG4gICAgICAgICAgICBtb2R1bGVTdWJzY3JpYmVycy5mb3JFYWNoKChzdWIpID0+IHN1YihjdXJyZW50U3RhdGUsIHByZXZTdGF0ZSkpXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICB9KVxuICB9LCBbXSlcblxuICBmdW5jdGlvbiBnZXRNb2R1bGVTdGF0ZTxUU3RhdGU+KHNpbXBsdXhNb2R1bGU6IFNpbXBsdXhNb2R1bGU8VFN0YXRlPikge1xuICAgIHJldHVybiAoXG4gICAgICBzaW1wbHV4TW9kdWxlLiRzaW1wbHV4Lm1vY2tTdGF0ZVZhbHVlIHx8XG4gICAgICBtb2R1bGVTdGF0ZXNbc2ltcGx1eE1vZHVsZS4kc2ltcGx1eC5uYW1lXSB8fFxuICAgICAgc2ltcGx1eE1vZHVsZS4kc2ltcGx1eC5nZXRTdGF0ZSgpXG4gICAgKVxuICB9XG5cbiAgZnVuY3Rpb24gc3Vic2NyaWJlVG9Nb2R1bGVTdGF0ZUNoYW5nZXMoXG4gICAgc2ltcGx1eE1vZHVsZTogU2ltcGx1eE1vZHVsZTxhbnk+LFxuICAgIGhhbmRsZXI6IFN0YXRlQ2hhbmdlSGFuZGxlcjxhbnk+LFxuICApIHtcbiAgICBjb25zdCBtb2R1bGVOYW1lID0gc2ltcGx1eE1vZHVsZS4kc2ltcGx1eC5uYW1lXG4gICAgY29uc3QgbW9kdWxlU3RhdGUgPSBnZXRNb2R1bGVTdGF0ZShzaW1wbHV4TW9kdWxlKVxuXG4gICAgaWYgKCFzdWJzY3JpYmVycy5oYXMobW9kdWxlTmFtZSkpIHtcbiAgICAgIHN1YnNjcmliZXJzLnNldChtb2R1bGVOYW1lLCBuZXcgU2V0KCkpXG4gICAgfVxuXG4gICAgc3Vic2NyaWJlcnMuZ2V0KG1vZHVsZU5hbWUpIS5hZGQoaGFuZGxlcilcblxuICAgIGhhbmRsZXIobW9kdWxlU3RhdGUsIG1vZHVsZVN0YXRlKVxuXG4gICAgcmV0dXJuICgpID0+IHN1YnNjcmliZXJzLmdldChtb2R1bGVOYW1lKSEuZGVsZXRlKGhhbmRsZXIpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGdldE1vZHVsZVN0YXRlLFxuICAgIHN1YnNjcmliZVRvTW9kdWxlU3RhdGVDaGFuZ2VzLFxuICB9XG59XG5cbi8qKlxuICogQSBwcm92aWRlciBmb3IgYWxsb3dpbmcgY29tcG9uZW50cyB0byB1c2Ugc3RhdGUgZnJvbSBzaW1wbHV4IG1vZHVsZXMuXG4gKlxuICogSXQgaXMgcmVjb21tZW5kZWQgdG8gd3JhcCB5b3VyIGVudGlyZSBhcHBsaWNhdGlvbiB3aXRoIGEgc2luZ2xlIHByb3ZpZGVyLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IFNpbXBsdXhQcm92aWRlcjogRnVuY3Rpb25Db21wb25lbnQ8eyBjaGlsZHJlbjogUmVhY3ROb2RlIH0+ID0gKHtcbiAgY2hpbGRyZW4sXG59KSA9PiB7XG4gIGNvbnN0IGNvbnRleHRWYWx1ZSA9IHVzZVNpbXBsdXhTdWJzY3JpcHRpb24oX2dldFN0b3JlUHJveHkpXG5cbiAgcmV0dXJuIChcbiAgICA8U2ltcGx1eENvbnRleHQuUHJvdmlkZXIgdmFsdWU9e2NvbnRleHRWYWx1ZX0+XG4gICAgICB7Y2hpbGRyZW59XG4gICAgPC9TaW1wbHV4Q29udGV4dC5Qcm92aWRlcj5cbiAgKVxufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFJTCxjQUFjLEdBRWYsTUFBTSxlQUFlLENBQUE7QUFDdEIsT0FBTyxLQUFLLEVBQUUsRUFFWixhQUFhLEVBR2IsVUFBVSxFQUNWLFNBQVMsRUFDVCxRQUFRLEdBQ1QsTUFBTSxPQUFPLENBQUE7QUFDZCxPQUFPLEVBQUUs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