- Notifications
You must be signed in to change notification settings - Fork1
Functions to serialize and hydrate state objects, partial immutables, and full immutables.
License
NotificationsYou must be signed in to change notification settings
noderaider/fire-hydrant
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
lightweight hydration and serialization of state, targeted at Redux Server Side Rendering and ImmutableJS
npm i -S fire-hydrant
Functions used to store state objects, partial immutables, and full immutables to strings and restore them back to their original state.
react-router andreact-router-redux with async routes example
import{createStore,applyMiddleware}from'redux'import{routerMiddleware}from'react-router-redux'import{combineReducers}from'redux'import*asreducersfrom'../reducers'exportdefaultfunctionconfigureStore(history,initialState){constreducer=combineReducers(reducers)constenhancer=applyMiddleware([routerMiddleware(history)])returncreateStore(reducer,initialState,enhancer)}
Plug this router into your server.use()
importReactfrom'react'importRouterfrom'router'importImmutablefrom'immutable'import{Provider}from'react-redux'import{createMemoryHistory,match,RouterContext}from'react-router'import{syncHistoryWithStore}from'react-router-redux'import{serialize,createInitialState}from'fire-hydrant'/** Routes can be direct server defined routes or a webpack bundle */importroutesfrom'./routes'constInitialState=({ state})=>{constserialized=serialize(state,{ Immutable})const__html=`window.__initialState__ =${serialized}`return<scriptdangerouslySetInnerHTML={{ __html}}/>}//-- ALTERNATE: Import createInitialState component factory for sanity checks and less boilerplate.constInitialState=createInitialState({ React, Immutable})constHTML=({ content, store})=>{conststate=store ?store.getState() :noop()return(<html><head><metacharSet="utf-8"/><title>Fire Hydrant</title></head><body><InitialStatestate={state}/><divid="root"dangerouslySetInnerHTML={{__html:content}}/><scriptsrc="/app.js"/></body></html>)}constrenderHTML=props=>`<!doctype html>${renderToString(<HTML{...props}/>)}`exportdefaultfunctioncreateRouter({ cors, paths}){constrouter=Router()router.use((req,res,next)=>{try{constmemoryHistory=createMemoryHistory(req.path)letstore=configureStore(memoryHistory)consthistory=syncHistoryWithStore(memoryHistory,store)match({ history, routes,location:req.url},(error,redirectLocation,renderProps)=>{if(error)res.status(500).send(error.message)elseif(redirectLocation)res.redirect(302,redirectLocation.pathname+redirectLocation.search)elseif(renderProps){constcontent=renderToString(<Providerstore={store}><RouterContext{...renderProps}/></Provider>)res.send(renderHTML({ content, store}))}elsenext()})}catch(routerError){res.status(500).send(process.env.NODE_ENV!=='production' ?routerError :'An error occurred rendering the application.')}})returnrouter}
Client entry point - This is where the state gets rehydrated.
importReactfrom'react'importImmutablefrom'immutable'import{render}from'react-dom'import{Provider}from'react-redux'import{match,Router,browserHistory}from'react-router'import{syncHistoryWithStore}from'react-router-redux'import{fromHydrant}from'fire-hydrant'importroutesfrom'./routes'/** Rehydrate our server built state that is stored in __initialState__ global */constinitialState=fromHydrant(window.__initialState__||{},{ Immutable})conststore=configureStore(browserHistory,initialState)consthistory=syncHistoryWithStore(browserHistory,store)constrootElement=document.getElementById('root')match({ history, routes},(err,redirectLocation,renderProps)=>{render(<Providerstore={store}><Router{...renderProps}/></Provider>,rootElement)})
constregularObj={a:'something',b:[1,2,3],c:{foo:{bar:true}}}constpartialImmutable={ ...regularObj,d:Immutable.Map({a:'foo',b:'bar'})}consttopLevelImmutable=Immutable.fromJS(regularObj)it('should toHydrant to an object',()=>expect(toHydrant({foo:'bar'})).toEqual(jasmine.any(Object)))it('should fromHydrant to an object',()=>expect(fromHydrant({foo:'bar'})).toEqual(jasmine.any(Object)))it('should serialize to a string',()=>expect(serialize({foo:'bar'})).toEqual(jasmine.any(String)))it('should deserialize to an object',()=>expect(deserialize(`{"foo": "bar"}`)).toEqual(jasmine.any(Object)))it('should be able to toHydrant and fromHydrant back for regular object',()=>{lethydrant=toHydrant(regularObj)letresult=fromHydrant(hydrant)expect(result).toEqual(regularObj)})it('should be able to toHydrant and fromHydrant back for partial immutable',()=>{lethydrant=toHydrant(partialImmutable)letresult=fromHydrant(hydrant)expect(result).toEqual(partialImmutable)})it('should be able to toHydrant and fromHydrant back for top level immutable',()=>{lethydrant=toHydrant(topLevelImmutable)letresult=fromHydrant(hydrant)expect(result).toEqual(topLevelImmutable)})it('should be able to serialize and deserialize to same values for regular object',()=>{letserialized=serialize(regularObj)letresult=deserialize(serialized)expect(result).toEqual(regularObj)})it('should be able to serialize and deserialize to same values for partial immutable',()=>{letserialized=serialize(partialImmutable)letresult=deserialize(serialized)expect(result).toEqual(partialImmutable)})it('should be able to serialize and deserialize to same values for top level immutable',()=>{letserialized=serialize(topLevelImmutable)letresult=deserialize(serialized)expect(result).toEqual(topLevelImmutable)})
About
Functions to serialize and hydrate state objects, partial immutables, and full immutables.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
No packages published
Uh oh!
There was an error while loading.Please reload this page.

