overmind-react
Version:
Functional actions
139 lines • 5.63 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createReactionHook = exports.createEffectsHook = exports.createActionsHook = exports.createStateHook = exports.Provider = void 0;
const React = require("react");
const overmind_1 = require("overmind");
const IS_PRODUCTION = overmind_1.ENVIRONMENT === 'production';
const IS_TEST = overmind_1.ENVIRONMENT === 'test';
const isNode = !IS_TEST &&
typeof process !== 'undefined' &&
process.title &&
process.title.includes('node');
function getFiberType(component) {
if (component.type) {
// React.memo
return getFiberType(component.type);
}
// React.forwardRef
return component.render || component;
}
// Inspired from https://github.com/facebook/react/blob/master/packages/react-devtools-shared/src/backend/renderer.js
function getDisplayName(component) {
const type = getFiberType(component);
return type.displayName || type.name || 'Anonymous';
}
function throwMissingContextError() {
throw new Error('The Overmind hook could not find an Overmind instance on the context of React. Please make sure you use the Provider component at the top of your application and expose the Overmind instance there. Please read more in the React guide on the website');
}
const context = React.createContext({});
let nextComponentId = 0;
exports.Provider = context.Provider;
function useForceRerender() {
const [flushId, forceRerender] = React.useState(-1);
return {
flushId,
forceRerender,
};
}
let currentComponentInstanceId = 0;
const { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: oldReactInternals, __CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE: newReactInternals, } = React;
const useCurrentComponent = () => {
var _a, _b, _c, _d, _e, _f, _g;
return ((_g = (_c = (_b = (_a = oldReactInternals === null || oldReactInternals === void 0 ? void 0 : oldReactInternals.ReactCurrentOwner) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.elementType) !== null && _c !== void 0 ? _c : (_f = (_e = (_d = newReactInternals === null || newReactInternals === void 0 ? void 0 : newReactInternals.A) === null || _d === void 0 ? void 0 : _d.getOwner) === null || _e === void 0 ? void 0 : _e.call(_d)) === null || _f === void 0 ? void 0 : _f.elementType) !== null && _g !== void 0 ? _g : {});
};
const useState = (cb) => {
const overmind = React.useContext(context);
if (!overmind.mode) {
throwMissingContextError();
}
if (isNode || overmind.mode.mode === overmind_1.MODE_SSR) {
return overmind.state;
}
const { forceRerender } = useForceRerender();
const trackStateTree = overmind.proxyStateTreeInstance.getTrackStateTree();
const state = cb ? cb(trackStateTree.state) : trackStateTree.state;
trackStateTree.track();
if (IS_PRODUCTION) {
React.useLayoutEffect(() => trackStateTree.subscribe((_, __, flushId) => {
forceRerender(flushId);
}), [trackStateTree]);
}
else {
const component = useCurrentComponent();
const name = getDisplayName(component);
component.__componentId =
typeof component.__componentId === 'undefined'
? nextComponentId++
: component.__componentId;
const { current: componentInstanceId } = React.useRef(currentComponentInstanceId++);
React.useEffect(() => {
overmind.eventHub.emitAsync(overmind_1.EventType.COMPONENT_ADD, {
componentId: component.__componentId,
componentInstanceId,
name,
paths: [],
});
return () => {
overmind.eventHub.emitAsync(overmind_1.EventType.COMPONENT_REMOVE, {
componentId: component.__componentId,
componentInstanceId,
name,
});
};
}, []);
React.useLayoutEffect(() => {
const dispose = trackStateTree.subscribe((_, __, flushId) => {
overmind.eventHub.emitAsync(overmind_1.EventType.COMPONENT_UPDATE, {
componentId: component.__componentId,
componentInstanceId,
name,
paths: Array.from(trackStateTree.pathDependencies),
flushId,
});
forceRerender(flushId);
});
return () => {
dispose();
};
}, [trackStateTree]);
}
return state;
};
const useActions = () => {
const overmind = React.useContext(context);
if (!overmind.mode) {
throwMissingContextError();
}
return overmind.actions;
};
const useEffects = () => {
const overmind = React.useContext(context);
if (!overmind.mode) {
throwMissingContextError();
}
return overmind.effects;
};
const useReaction = () => {
const overmind = React.useContext(context);
if (!overmind.mode) {
throwMissingContextError();
}
return overmind.reaction;
};
const createStateHook = () =>
// eslint-disable-next-line dot-notation
useState;
exports.createStateHook = createStateHook;
const createActionsHook = () => {
return useActions;
};
exports.createActionsHook = createActionsHook;
const createEffectsHook = () => {
return useEffects;
};
exports.createEffectsHook = createEffectsHook;
const createReactionHook = () => {
return useReaction;
};
exports.createReactionHook = createReactionHook;
//# sourceMappingURL=index.js.map