UNPKG

reactive-state

Version:

Redux-like state management using RxJS and TypeScript

140 lines 6.15 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.useStoreSlices = exports.useStoreState = exports.useStore = exports.WithStore = exports.StoreProjection = exports.StoreSlice = exports.StoreConsumer = exports.StoreProvider = void 0; var React = require("react"); var context = React.createContext(undefined); var Provider = context.Provider, Consumer = context.Consumer; var StoreProvider = /** @class */ (function (_super) { __extends(StoreProvider, _super); function StoreProvider() { return _super !== null && _super.apply(this, arguments) || this; } StoreProvider.prototype.render = function () { return React.createElement(Provider, { value: this.props.store }, this.props.children); }; return StoreProvider; }(React.Component)); exports.StoreProvider = StoreProvider; exports.StoreConsumer = Consumer; var StoreSlice = /** @class */ (function (_super) { __extends(StoreSlice, _super); function StoreSlice() { return _super !== null && _super.apply(this, arguments) || this; } StoreSlice.prototype.componentWillUnmount = function () { this.slice.destroy(); }; StoreSlice.prototype.render = function () { var _this = this; return (React.createElement(Consumer, null, function (store) { if (!store) throw new Error("StoreSlice used outside of a Store context. Did forget to add a <StoreProvider>?"); // we ignore this else due to a limitation in enzyme - we can't trigger a // forceUpdate here to test the else branch; /* istanbul ignore else */ if (_this.slice === undefined) { _this.slice = store.createSlice(_this.props.slice(store), _this.props.initialState, _this.props.cleanupState); } return React.createElement(Provider, { value: _this.slice }, _this.props.children); })); }; return StoreSlice; }(React.Component)); exports.StoreSlice = StoreSlice; exports.StoreProjection = /** @class */ (function (_super) { __extends(StoreProjection, _super); function StoreProjection() { return _super !== null && _super.apply(this, arguments) || this; } StoreProjection.prototype.componentWillUnmount = function () { this.slice.destroy(); }; StoreProjection.prototype.render = function () { var _this = this; return (React.createElement(Consumer, null, function (store) { if (!store) throw new Error("StoreProjection/Slice used outside of a Store context. Did forget to add a <StoreProvider>?"); // we ignore this else due to a limitation in enzyme - we can't trigger a // forceUpdate here to test the else branch; /* istanbul ignore else */ if (_this.slice === undefined) { _this.slice = store.createProjection(_this.props.forwardProjection, _this.props.backwardProjection, _this.props.initial, _this.props.cleanup); } return React.createElement(Provider, { value: _this.slice }, _this.props.children); })); }; return StoreProjection; }(React.Component)); var WithStore = /** @class */ (function (_super) { __extends(WithStore, _super); function WithStore() { return _super !== null && _super.apply(this, arguments) || this; } WithStore.prototype.render = function () { var _this = this; return (React.createElement(Consumer, null, function (store) { var child = _this.props.children; if (!store) throw new Error("WithStore used but no store could be found in context. Did you suppliy a StoreProvider?"); else if (typeof _this.props.children !== "function") throw new Error("WithStore used but its child is not a function."); else return child(store); })); }; return WithStore; }(React.Component)); exports.WithStore = WithStore; /** * A react hook to obtain the current store, depending on the context. */ function useStore() { var store = React.useContext(context); if (store === undefined) { throw new Error("No store found in context, did you forget to add a Provider for it?"); } return store; } exports.useStore = useStore; function useStoreState(projection) { var store = useStore(); var _a = React.useState(projection ? projection(store.currentState) : store.currentState), slice = _a[0], setSlice = _a[1]; // do not introduce a unneeded second re-render whenever using this hook var firstRender = React.useRef(true); React.useEffect(function () { var sub = store.watch(projection).subscribe(function (slice) { if (!firstRender.current) { setSlice(slice); } }); firstRender.current = false; return function () { return sub.unsubscribe(); }; }, [store]); return slice; } exports.useStoreState = useStoreState; /** * A react hook to create a fluent interface for producing a hook that makes state slices. * Useful mainly for infering the type of the slice; when the type of slice is known, useStoreState is cleaner. */ function useStoreSlices() { // note: a named function is needed here to keep react devtools looking clean return function useStoreSlice(projection) { return useStoreState(projection); }; } exports.useStoreSlices = useStoreSlices; //# sourceMappingURL=provider.js.map