UNPKG

zippy-store

Version:

A lightweight and versatile global state management solution designed for seamless integration in both JavaScript and React applications. Provides a simple and efficient way to manage shared state across components and even in non-React JavaScript environ

156 lines 7.08 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; const isReactNative = () => { return typeof navigator !== 'undefined' && navigator.product === 'ReactNative'; }; class StoreManager { constructor() { this.stores = {}; // Use a more specific type this.persistStoreKeys = {}; this.getStore = (storeKey) => { return this.stores[storeKey]; // Type assertion for safety }; this.getState = (storeKey) => { const store = this.getStore(storeKey); return store ? JSON.parse(JSON.stringify(store.state)) : undefined; // Deep copy }; this.getActions = (storeKey) => { var _a; const actions = (_a = this.stores[storeKey]) === null || _a === void 0 ? void 0 : _a.actions; return Object.assign({}, actions); }; this.setState = (storeKey, newStateCb) => __awaiter(this, void 0, void 0, function* () { const store = this.getStore(storeKey); if (!store) { throw new Error(`Store with key "${storeKey}" not initialized.`); } const state = this.getState(storeKey); // Assertion is safe here as getState does deep copy const storeUpdates = typeof newStateCb === 'function' ? yield newStateCb(state) : newStateCb; store.state = Object.assign(Object.assign({}, state), storeUpdates); this.notifySubscribers(storeKey); if (this.persistStoreKeys[storeKey]) { this.setLocalStorageItem(storeKey, store.state); } }); this.notifySubscribers = (storeKey) => { const store = this.getStore(storeKey); if (!store) { return; } for (const symbol of Object.getOwnPropertySymbols(store.subscribers)) { if (typeof symbol === 'symbol') { // Ensure it's a symbol store.subscribers[symbol](this.getState(storeKey)); } } }; this.setStateCreator = (storeKey) => { return (cb) => this.setState(storeKey, (state) => typeof cb === 'function' ? cb(state) : cb); }; // private getAsyncLocalStorageItem = async <T extends State>(key: string = '', initialState: T) => { // try { // const AsyncStorage = (await import('@react-native-async-storage/async-storage')).default; // const value = await AsyncStorage.getItem(key); // const localStorageState = value ? JSON.parse(value) : null; // if (localStorageState) { // this.setState(key, localStorageState) // } // } catch (e) { // console.error(e); // return null; // } // } // private setAsyncLocalStorageItem = async <T extends State>(key: string, value: T) => { // try { // const AsyncStorage = (await import('@react-native-async-storage/async-storage')).default; // const stringValue = JSON.stringify(value); // await AsyncStorage.setItem(key, stringValue); // } catch (e) { // console.error(e); // } // } this.getLocalStorageItem = (key = '', initialState) => { try { if (!isReactNative()) { const localStorageState = JSON.parse(localStorage.getItem(key) || 'null'); return localStorageState ? localStorageState : initialState; } else { // this.getAsyncLocalStorageItem(key, initialState); // async storage return null; } } catch (e) { console.error(e); return null; } }; this.setLocalStorageItem = (key, value) => __awaiter(this, void 0, void 0, function* () { try { const stringValue = JSON.stringify(value); if (!isReactNative()) { localStorage.setItem(key, stringValue); } else { // this.setAsyncLocalStorageItem(key, value); // async storage } } catch (e) { console.error(e); } }); this.store = { createStore: (storeKey, stateAndActionsFn, persist = false) => { this.persistStoreKeys[storeKey] = persist; let store = this.getStore(storeKey); if (!store) { const initialStateAndActions = stateAndActionsFn(this.setStateCreator(storeKey), () => this.getState(storeKey)); const state = {}; const actions = {}; for (const key in initialStateAndActions) { if (typeof initialStateAndActions[key] !== "function") { state[key] = initialStateAndActions[key]; } else { actions[key] = initialStateAndActions[key]; } } let localStorageState = undefined; if (persist) { localStorageState = this.getLocalStorageItem(storeKey, state); } store = { state: localStorageState || state, subscribers: {}, actions: actions, }; this.stores[storeKey] = store; // Store the created store } return { dispatch: Object.assign({}, store.actions) }; // Return a copy to prevent direct mutation }, setState: this.setState, getState: this.getState, dispatch: this.getActions, subscribe: (key, cb) => { const store = this.getStore(key); if (!store) { throw new Error(`Store with key "${key}" not initialized.`); } const uuid = Symbol(); store.subscribers[uuid] = cb; return () => { delete store.subscribers[uuid]; }; }, }; } } const storeManagerInstance = new StoreManager(); export default storeManagerInstance.store; //# sourceMappingURL=store.js.map