state_create.js

import { zustand as create } from '@gravityforms/libraries';
import { filterObject } from '@gravityforms/utils';

/**
 * @module createWrapper
 * @description Wrapper around zustand store to allow you to extract all data separate from methods if needed.
 *
 * @since 1.0.0
 *
 * @param {object}   data    Initial state of store.
 * @param {Function} actions Store actions.
 *
 * @return {*}
 *
 * @example
 * import { create } from '@gravityforms/react-utils';
 * import config from 'gform-admin-config';
 *
 * const initialState = config?.components?.setup_wizard?.data?.defaults || {};
 *
 * const storeActions = ( set ) => ( {
 * 	closeDialog: () => set( () => ( { isOpen: false } ) ),
 * 	patchServices: ( checked, e ) => set( produce( ( draft ) => {
 * 		draft.services.forEach( ( type, i ) => {
 * 			if ( type.value === e.target.value ) {
 * 				draft.services[ i ].initialChecked = checked;
 * 			}
 * 			if ( e.target.value === 'other' && ! checked ) {
 * 				draft.servicesOther = '';
 * 			}
 * 		} );
 * 	} ) ),
 * 	setActiveStepNext: () => set( ( state ) => ( { activeStep: state.activeStep + 1 } ) ),
 * 	setActiveStepPrevious: () => set( ( state ) => ( { activeStep: state.activeStep - 1 } ) ),
 * } );
 *
 * const useStore = create( initialState, storeActions );
 *
 * export default useStore;
 *
 */
const createWrapper = ( data, actions ) => {
	const store = create( ( set ) => ( {
		...data,
		...actions( set ),
	} ) );

	store.getData = () => {
		const all = store.getState();
		return filterObject( all, ( [ key ] ) => data[ key ] !== undefined );
	};

	store.getActions = () => {
		const all = store.getState();
		const actionsObj = actions();
		return filterObject( all, ( [ key ] ) => actionsObj[ key ] !== undefined );
	};

	return store;
};

export default createWrapper;