"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useStateWithHistory = void 0; var react_1 = require("react"); var useFirstMountState_1 = require("./useFirstMountState"); var hookState_1 = require("./misc/hookState"); function useStateWithHistory(initialState, capacity, initialHistory) { if (capacity === void 0) { capacity = 10; } if (capacity < 1) { throw new Error("Capacity has to be greater than 1, got '" + capacity + "'"); } var isFirstMount = useFirstMountState_1.useFirstMountState(); var _a = react_1.useState(initialState), state = _a[0], innerSetState = _a[1]; var history = react_1.useRef((initialHistory !== null && initialHistory !== void 0 ? initialHistory : [])); var historyPosition = react_1.useRef(0); // do the states manipulation only on first mount, no sense to load re-renders with useless calculations if (isFirstMount) { if (history.current.length) { // if last element of history !== initial - push initial to history if (history.current[history.current.length - 1] !== initialState) { history.current.push(initialState); } // if initial history bigger that capacity - crop the first elements out if (history.current.length > capacity) { history.current = history.current.slice(history.current.length - capacity); } } else { // initiate the history with initial state history.current.push(initialState); } historyPosition.current = history.current.length && history.current.length - 1; } var setState = react_1.useCallback(function (newState) { innerSetState(function (currentState) { newState = hookState_1.resolveHookState(newState, currentState); // is state has changed if (newState !== currentState) { // if current position is not the last - pop element to the right if (historyPosition.current < history.current.length - 1) { history.current = history.current.slice(0, historyPosition.current + 1); } historyPosition.current = history.current.push(newState) - 1; // if capacity is reached - shift first elements if (history.current.length > capacity) { history.current = history.current.slice(history.current.length - capacity); } } return newState; }); }, [state, capacity]); var historyState = react_1.useMemo(function () { return ({ history: history.current, position: historyPosition.current, capacity: capacity, back: function (amount) { if (amount === void 0) { amount = 1; } // don't do anything if we already at the left border if (!historyPosition.current) { return; } innerSetState(function () { historyPosition.current -= Math.min(amount, historyPosition.current); return history.current[historyPosition.current]; }); }, forward: function (amount) { if (amount === void 0) { amount = 1; } // don't do anything if we already at the right border if (historyPosition.current === history.current.length - 1) { return; } innerSetState(function () { historyPosition.current = Math.min(historyPosition.current + amount, history.current.length - 1); return history.current[historyPosition.current]; }); }, go: function (position) { if (position === historyPosition.current) { return; } innerSetState(function () { historyPosition.current = position < 0 ? Math.max(history.current.length + position, 0) : Math.min(history.current.length - 1, position); return history.current[historyPosition.current]; }); }, }); }, [state]); return [state, setState, historyState]; } exports.useStateWithHistory = useStateWithHistory;