UNPKG

state-pool

Version:

Transform your React app with our state management library! Declare global and local states like variables, powered by the magic of React hooks 🪄✨

149 lines (148 loc) • 5.63 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createState = exports.createDerivedState = exports.DerivedState = void 0; var immer_1 = require("immer"); var useState_1 = __importDefault(require("./useState")); var useReducer_1 = __importDefault(require("./useReducer")); var State = /** @class */ (function () { function State(initialValue) { if (typeof initialValue === "function") { this.value = initialValue(); } else { this.value = initialValue; } this.subscribers = []; } State.prototype.getValue = function (selector) { if (selector) { return selector(this.value); } return this.value; }; State.prototype.refresh = function () { this.subscribers.forEach(function (subscriber) { if (subscriber.refresh) { subscriber.refresh(); } }); }; State.prototype.setValue = function (newValue, config) { if (config === void 0) { config = {}; } if (newValue === undefined) { this.__updateValue(function (draftVal) { return immer_1.nothing; }, // nothing is equivalent to undefined config); } else if (typeof newValue === 'function') { var reducer = newValue; this.setValue(reducer(this.getValue(config.selector)), config); } else { this.__updateValue(function (draftVal) { return newValue; }, config); } }; State.prototype.updateValue = function (stateModifier, config) { if (config === void 0) { config = {}; } var stateModifierWrapper = function (draftState) { // This wrapper is for disabling setting returned value // We don't allow returned value to be set(just return undefined) stateModifier(draftState); }; this.__updateValue(stateModifierWrapper, config); }; State.prototype.__updateValue = function (stateUpdater, config) { // No need to do a lot of type checking here bcuz this is an internal method var selector = config.selector; var patcher = config.patcher; var oldState = this.value; var newState; if (selector && patcher) { // Update the selected node first and get its value var selectedNodeValue_1 = (0, immer_1.produce)(selector(oldState), stateUpdater); // Here we're patching back the updated selected node to the main state newState = (0, immer_1.produce)(oldState, function (draftCurrentState) { // Avoid setting returns patcher(draftCurrentState, selectedNodeValue_1); }); } else { newState = (0, immer_1.produce)(oldState, stateUpdater); } this.value = newState; if (newState !== oldState) { // There's a new update this.subscribers.forEach(function (subscriber) { if (subscriber.selector(newState) !== subscriber.selector(oldState)) { // Node value has changed subscriber.observer(subscriber.selector(newState)); } }); } }; State.prototype.subscribe = function (itemToSubscribe) { var _this = this; var _itemToSubscribe; if (typeof itemToSubscribe === 'function') { var selector = function (state) { return state; }; _itemToSubscribe = { observer: itemToSubscribe, selector: selector }; } else { _itemToSubscribe = itemToSubscribe; } if (this.subscribers.indexOf(_itemToSubscribe) === -1) { // Subscribe a component to this state this.subscribers.push(_itemToSubscribe); } ; var unsubscribe = function () { _this.subscribers = _this.subscribers.filter(function (subscriber) { return (subscriber !== _itemToSubscribe); }); }; return unsubscribe; }; State.prototype.select = function (selector) { return createDerivedState(this, selector); }; State.prototype.useState = function (config) { if (config === void 0) { config = {}; } return (0, useState_1.default)(this, config); }; State.prototype.useReducer = function (reducer, config) { if (config === void 0) { config = {}; } return (0, useReducer_1.default)(reducer, this, config); }; return State; }()); exports.default = State; var DerivedState = /** @class */ (function () { function DerivedState(State, selector) { this.State = State; this.selector = selector; } DerivedState.prototype.getValue = function () { return this.State.getValue(this.selector); }; DerivedState.prototype.subscribe = function (observer, refresh) { var itemToSubscribe = { observer: observer, selector: this.selector, refresh: refresh }; return this.State.subscribe(itemToSubscribe); }; return DerivedState; }()); exports.DerivedState = DerivedState; function createDerivedState(State, selector) { return new DerivedState(State, selector); } exports.createDerivedState = createDerivedState; function createState(initialValue) { return new State(initialValue); } exports.createState = createState;