import React, { Context, ReactNode, useState, createContext, useMemo } from 'react'; import { useCookies, CookiesProvider } from 'react-cookie'; import Cookies, { Cookie, CookieSetOptions } from 'universal-cookie'; import Debug from 'debug'; import { IStoreContext, defaultContext, useStore } from './store'; const debug = Debug('deepcase:store:cookie'); export const CookiesStoreContext = createContext(defaultContext); export const CookiesStoreProvider = ({ context = CookiesStoreContext, children, defaultCookies, options = {}, }: { context?: Context; children?: ReactNode; defaultCookies?: Cookie; options?: CookieSetOptions; }) => { const [cookies] = useState(() => defaultCookies && new Cookies(defaultCookies)); return {children} ; }; export const CookiesStoreProviderCore = ({ context = CookiesStoreContext, children, defaultCookies = {}, options = {}, }: { context?: Context; children?: ReactNode; defaultCookies?: any; options?: CookieSetOptions; }) => { const [useStore] = useState(() => { return function useStore( key: string, defaultValue: T, ): [T, (value: T) => any, () => any] { const memoDefaultValue = useMemo(() => defaultValue, []); const [cookie, setCookie, removeCookie] = useCookies([key]); const [setValue] = useState(() => (value) => { debug('setValue', { key, defaultValue: memoDefaultValue, value, options }); return setCookie(key, { value }, options); }); const [unsetValue] = useState(() => () => { debug('unsetValue', { key, defaultValue: memoDefaultValue, options }); return removeCookie(key, options); }); let defaultCookie; try { defaultCookie = defaultCookies && defaultCookies[key] && typeof(defaultCookies[key]) === 'string' ? JSON.parse(defaultCookies[key]).value : defaultCookies[key]; } catch (error) { debug('setStore:error', { error, key, defaultValue: memoDefaultValue, defaultCookie: defaultCookies[key] }); } return [(cookie[key] && cookie[key].value) || (defaultCookies && defaultCookie) || memoDefaultValue, setValue, unsetValue]; }; }); return {children} ; }; export function useCookiesStore(key: string, defaultValue: T, context = CookiesStoreContext) { return useStore(key, defaultValue, context); }