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
JavaScript
;
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;