UNPKG

@frauschert/yas

Version:

Yet Another State - A lightweight and type-safe state management solution for React

106 lines (105 loc) 2.22 kB
import { useSyncExternalStore as h, useCallback as y } from "react"; function S(t, r) { if (t === r) return !0; if (typeof t != "object" || t === null || typeof r != "object" || r === null) return !1; const n = Object.keys(t), e = Object.keys(r); if (n.length !== e.length) return !1; for (const c of n) if (!e.includes(c) || !S( t[c], r[c] )) return !1; return !0; } function k(t, r, ...n) { let e = t, c = t; const u = /* @__PURE__ */ new Set(), s = r || S; function p() { return e; } function d() { return t; } function g() { return c; } let f = (a) => { const o = a(e); c = e, e = o, u.forEach((i) => i(e, c)); }; const l = { getState: p, getInitialState: d, getPreviousState: g, setState: f, subscribe: (a) => (u.add(a), () => { u.delete(a); }) }; if (n.length > 0) { const a = n.slice().reverse().reduce( (o, i) => i(l)(o), (o) => f(() => o) ); f = (o) => { const i = o(e); s(e, i) || a(i); }; } return { ...l, setState: f }; } function b(t) { return (r) => h( t.subscribe, y(() => r(t.getState()), [t, r]) ); } function m(t) { return (r) => Object.fromEntries( Object.entries(r).map(([n, e]) => [ n, (...c) => t.setState((u) => e(u, ...c)) ]) ); } function E({ initialState: t, actions: r, equalityFn: n, middleware: e = [] }) { const c = k(t, n, ...e), u = b(c), s = m(c)(r); return { useStore: u, actions: s, api: c }; } function O(t, r = 50) { const n = [], e = []; return { ...t, setState: (u) => { const s = t.getState(); t.setState(u), n.push(s), n.length > r && n.shift(), e.length = 0; }, undo: () => { if (!n.length) return; const u = t.getState(), s = n.pop(); e.push(u), t.setState(() => s); }, redo: () => { if (!e.length) return; const u = t.getState(), s = e.pop(); n.push(u), t.setState(() => s); }, canUndo: () => n.length > 0, canRedo: () => e.length > 0, clearHistory: () => { n.length = 0, e.length = 0; } }; } export { E as create, k as createStore, O as makeUndoable };