reactive-state
Version:
Redux-like state management using RxJS and TypeScript
140 lines • 6.15 kB
JavaScript
;
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