'use strict'; const React = require('react'); const vanilla_index = require('./shared/stan-js.604020da.cjs'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } const React__default = /*#__PURE__*/_interopDefaultCompat(React); const createStore = (stateRaw) => { const storeKeys = Object.keys(stateRaw); const store = vanilla_index.createStore(stateRaw); const getState = () => { let oldState; return () => { const currentState = { ...store.getState() }; if (vanilla_index.equal(oldState, currentState)) { return oldState; } oldState = currentState; return currentState; }; }; const useStore = () => { const [isInitialized, setIsInitialized] = React.useState(false); const [subscribeKeys] = React.useState(() => /* @__PURE__ */ new Set()); const getSnapshot = React.useMemo(() => { if (subscribeKeys.size === 0) { return store.getState; } return getState(); }, [isInitialized]); const subscribeStore = React.useMemo(() => { if (subscribeKeys.size === 0) { return () => () => { }; } return store.subscribe(Array.from(subscribeKeys)); }, [isInitialized]); const synced = React.useSyncExternalStore(subscribeStore, getSnapshot, getSnapshot); if (isInitialized) { return { ...synced, ...store.actions }; } return new Proxy({ ...synced, ...store.actions }, { get: (target, key) => { if (storeKeys.includes(key) && !subscribeKeys.has(key)) { subscribeKeys.add(key); setIsInitialized(true); } if (vanilla_index.keyInObject(key, target)) { return target[key]; } return void 0; } }); }; const useStoreEffect = (run, deps = []) => { const isMounted = React.useRef(false); const callbackRef = React.useRef(run); React.useEffect(() => { const dispose = store.effect((state) => callbackRef.current(state)); return dispose; }, []); React.useEffect(() => { callbackRef.current = run; }, [run]); React.useEffect(() => { if (!isMounted.current) { isMounted.current = true; return; } run(store.getState()); }, deps); }; const getAction = (key) => store.actions[vanilla_index.getActionKey(key)]; const useHydrateState = (state) => { const isMounted = React.useRef(false); if (!isMounted.current) { isMounted.current = true; store.batchUpdates(() => Object.entries(state).forEach(([key, value]) => getAction(key)?.(value))); } }; return { actions: store.actions, getState: store.getState, effect: store.effect, reset: store.reset, batchUpdates: store.batchUpdates, /** * React's hook that allows to access store's values and to update them * @returns Store's values and actions * @see {@link https://codemask-labs.github.io/stan-js/reference/createstore#useStore} */ useStore, /** * React's hook that allows to subscribe to store's values and react to them by calling the listener callback * @param run - callback that will be called when store's values change * @see {@link https://codemask-labs.github.io/stan-js/reference/createstore#useStoreEffect} */ useStoreEffect, /** * React's hook that allows to hydrate store's state with the provided values once on mount * @param state - values that should be used to hydrate the store * @see {@link https://codemask-labs.github.io/stan-js/reference/createstore#useHydrateState} */ useHydrateState }; }; const createScopedStore = (initialState) => { const StoreContext = React.createContext(createStore(initialState)); const useScopedStore = () => React.useContext(StoreContext); StoreContext.displayName = "stan-js"; const useStore = () => { const { useStore: useStore2 } = React.useContext(StoreContext); return useStore2(); }; const useStoreEffect = (run, deps = []) => { const { useStoreEffect: useStoreEffect2 } = React.useContext(StoreContext); useStoreEffect2(run, deps); }; const StoreProvider = ({ children, initialValue }) => { const [store] = React.useState(() => createStore(vanilla_index.mergeState(initialState, initialValue ?? {}))); const isMounted = React.useRef(false); React.useEffect(() => { if (!isMounted.current) { isMounted.current = true; return; } store.batchUpdates( () => Object.entries(initialValue ?? {}).forEach(([key, value]) => { store.actions[vanilla_index.getActionKey(key)](value); }) ); }, [initialValue]); return /* @__PURE__ */ React__default.createElement(StoreContext.Provider, { children, value: store }); }; const withStore = (Component, initialValue) => (props) => /* @__PURE__ */ React__default.createElement(StoreProvider, { initialValue }, /* @__PURE__ */ React__default.createElement(Component, { ...props })); return { StoreProvider, useScopedStore, withStore, useStore, useStoreEffect }; }; exports.createScopedStore = createScopedStore; exports.createStore = createStore;