UNPKG

@naverpay/vanilla-store

Version:

![NPM Version](https://img.shields.io/npm/v/%40naverpay%2Fvanilla-store) ![NPM bundle size](https://img.shields.io/bundlephobia/min/%40naverpay%2Fvanilla-store) ![NPM Downloads](https://img.shields.io/npm/dw/%40naverpay%2Fvanilla-store)

63 lines (62 loc) 2.11 kB
import { useRef, useEffect, useSyncExternalStore } from "react"; import { shallowEqual } from "./shallowEqual.mjs"; function useSyncStore(store, initialValue) { const value = useSyncExternalStore(store.subscribe, store.get, () => initialValue || store.get()); return value; } const isNil = (value) => value == null; function useSyncWithInitialValue(store, initialValue) { const ref = useRef(initialValue || null); useEffect(() => { const serialized = store.persistStore?.serialized; const persistValue = store.persistStore?.value; if (!isNil(serialized) && !isNil(persistValue)) { store.set(persistValue); ref.current = null; return; } if (!isNil(ref.current)) { store.set(ref.current); ref.current = null; } }, [store]); } function useStore(store, initialValue) { useSyncWithInitialValue(store, initialValue); const value = useSyncStore(store, initialValue); return [value, store.set]; } const useGetStore = (store, initialValue) => { useSyncWithInitialValue(store, initialValue); const value = useSyncStore(store, initialValue); return value; }; function useSetStore(store, initialValue) { useSyncWithInitialValue(store, initialValue); return store.set; } function useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, selector, isEqual = shallowEqual) { const initialSelection = selector(getSnapshot()); const stateRef = useRef(initialSelection); const snapshot = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); const selection = selector(snapshot); if (!isEqual(selection, stateRef.current)) { stateRef.current = selection; } return stateRef.current; } function useStoreSelector(store, selector, options) { const { initialStoreValue, isEqual } = options || {}; useSyncWithInitialValue(store, initialStoreValue); const value = useSyncExternalStoreWithSelector(store.subscribe, store.get, () => initialStoreValue || store.get(), selector, isEqual); return [value, store.set]; } export { useGetStore, useSetStore, useStore, useStoreSelector };