UNPKG

gridiron-example

Version:

Example webpack project for gridiron and related components. Showcases what can be done with gridiron.

144 lines (122 loc) 5.18 kB
import cookie from 'react-cookie' import { client, log, noop } from '../../config' const { state } = client const keyNames = Object.keys(state.meta) const separator = ':' const stateSerializers = { json: state => JSON.stringify(state) , concat: state => state.join(separator) , base64: state => new Buffer(state).toString('base64') } const stateDeserializers = { json: serialized => JSON.parse(serialized) , concat: serialized => serialized.split(separator) , base64: serialized => new Buffer(serialized, 'base64').toString('ascii') } function getStateMeta(key) { let stateMeta = state.meta[key] if(!stateMeta) throw new Error(`Unsupported state => '${stateKey}'. Supported states: ['${JSON.stringify([...keyNames])}']`) return stateMeta } function getStores(stateKeys = keyNames) { let stores = {} for(let stateKey of stateKeys) { let stateMeta = getStateMeta(stateKey) let serialize = getSerializer(stateMeta) let deserialize = getDeserializer(stateMeta) stores[stateKey] = getPersistMedium({ persist: stateMeta.persist , serialize , deserialize }) } return stores } function getSerializer({ jsonProps, concatProps, base64Props }) { if(jsonProps && concatProps) throw new Error('Cannot serialize using jsonProps and concatProps (concatProps should only be used on array state).') let serializers = [] if(jsonProps) serializers.push(stateSerializers.json) if(concatProps) serializers.push(stateSerializers.concat) if(base64Props) serializers.push(stateSerializers.base64) return state => { //log.warn({ state }, 'SERIALIZER') return serializers.reduce((mutated, serialize) => serialize(mutated), state) } } function getDeserializer({ jsonProps, concatProps, base64Props, defaultProps = noop() }) { if(jsonProps && concatProps) throw new Error('Cannot serialize using jsonProps and concatProps (concatProps should only be used on array state).') let deserializers = [] if(base64Props) deserializers.push(stateDeserializers.base64) if(concatProps) deserializers.push(stateDeserializers.concat) if(jsonProps) deserializers.push(stateDeserializers.json) return serialized => { //log.warn({ serialized }, 'DESERIALIZER') return typeof serialized === 'undefined' ? defaultProps : deserializers.reduce((mutated, deserialize) => deserialize(mutated), serialized) } } function getPersistMedium({ persist, serialize, deserialize }) { switch(persist.type) { case 'cookie': return { load: () => deserialize(cookie.load(persist.name)) , save: state => cookie.save(persist.name, serialize(state), cookieOpts(persist)) , remove: () => cookie.save(persist.name, noop(), cookieOpts({...persist, days: -1})) } case 'local': return { load: () => deserialize(localStorage.getItem(persist.name)) , save: state => localStorage.setItem(persist.name, serialize(state)) , remove: () => localStorage.removeItem(persist.name) } case 'session': return { load: () => deserialize(sessionStorage.getItem(persist.name)) , save: state => sessionStorage.setItem(persist.name, serialize(state)) , remove: () => sessionStorage.removeItem(persist.name) } } } const cookieOpts = persist => ( { path: '/' , expires: getFutureDate(persist.days || 1) , secure: persist.setSecureCookie || false , httpOnly: persist.httpOnly || false } ) function getFutureDate(days) { let futureDate = new Date() futureDate.setDate(futureDate.getDate()+days) return futureDate } export default (stores = getStores()) => { const loadState = (stateKeys = keyNames) => { let state = {} for(let stateKey of stateKeys) state[stateKey] = stores[stateKey].load() return state } const saveState = partialState => { //log.warn({ partialState }, 'saveState') let fullState = {} for(let stateKey of Object.keys(partialState)) { stores[stateKey].save(partialState[stateKey]) fullState[stateKey] = state } return fullState } const removeState = stateKeys => { //log.warn({ stateKeys }, 'removeState') if(!stateKeys) throw new Error('Must supply stateKeys to remove from state.') let fullState = loadState() for(let stateKey of stateKeys) { stores[stateKey].remove() fullState[stateKey] = noop() } return fullState } /** Loads all the common cookie details */ const getPersisted = () => loadState(['tokens', 'fingerprint']) return { loadState, saveState, removeState, getPersisted } }