Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

localForage support? #3

Open
k1sul1 opened this issue Mar 14, 2018 · 5 comments
Open

localForage support? #3

k1sul1 opened this issue Mar 14, 2018 · 5 comments

Comments

@k1sul1
Copy link

k1sul1 commented Mar 14, 2018

While this plugin works great as is, localStorage is a bit problematic with the size limits and so on. I'm not worried that my app state will ever exceed 5MB, but I'd like to store it elsewhere anyway, partially because I'm already using localForage for other things, and would want to save localForage for something more critical. Or something.

Since localForage and localStorage have similar APIs (w/ the exception of localForage being async), I tried it myself with the following fork, but it obviously didn't work, something else is clearly happening behind the scenes, but I've no idea what.

import { appState } from './DiskStorage'
let storageCache = {}

let hasLocalForage = true
let storage = appState

export default {
  name: 'localForage',

  // can be used globally and locally
  global: true,
  local: true,

  // reducerObjects is an object with the following structure:
  // { key: { reducer, value, type, options } }
  mutateReducerObjects (input, output, reducerObjects) {
    if (hasLocalForage && input.path) {
      Object.keys(reducerObjects).filter(key => reducerObjects[key].options && reducerObjects[key].options.persist).forEach(key => {
        const path = `${output.path.join('.')}.${key}`
        const defaultValue = reducerObjects[key].value
        const defaultReducer = reducerObjects[key].reducer

        const value = storage[path] ? JSON.parse(storage[path]) : defaultValue
        storageCache[path] = value

        const reducer = (state = value, payload) => {
          const result = defaultReducer(state, payload)
          if (storageCache[path] !== result) {
            storageCache[path] = result
            storage[path] = JSON.stringify(result)
          }
          return result
        }

        reducerObjects[key].reducer = reducer
        reducerObjects[key].value = value
      })
    }
  },

  clearCache () {
    storageCache = {}
  }
}

appState is simply export const appState = localforage.createInstance({ name: 'appState' }).

This is how I've created the store:

import { getStore } from 'kea'

import createHistory from 'history/createBrowserHistory'
import { routerReducer, routerMiddleware } from 'react-router-redux'

import sagaPlugin from 'kea-saga/es'
// import localStoragePlugin from 'kea-localstorage/es'
import localForagePlugin from './lib/keaLocalForage'

export const history = createHistory()

export const store = getStore({
  middleware: [
    routerMiddleware(history)
  ],
  reducers: {
    router: routerReducer,
  },
  plugins: [
    sagaPlugin,
    // localStoragePlugin
    localForagePlugin,
  ]
})

So, any plans for localForage? 🤔

@sanchezweezer
Copy link

I think you can just pass storageEngine option to the plugin, so currently this plugin you can adjust to your needs, imho

@sanchezweezer
Copy link

So i'm think this should work:

import { getStore } from 'kea'

import createHistory from 'history/createBrowserHistory'
import { routerReducer, routerMiddleware } from 'react-router-redux'

import sagaPlugin from 'kea-saga/es'
import localStoragePlugin from 'kea-localstorage';
// import localForagePlugin from './lib/keaLocalForage'

export const history = createHistory()

export const store = getStore({
  middleware: [
    routerMiddleware(history)
  ],
  reducers: {
    router: routerReducer,
  },
  plugins: [
    sagaPlugin,
    localStoragePlugin({
            storageEngine: localforage.createInstance({ name: 'appState' }) // or other store instance
        }),
  ]
})

@sanchezweezer
Copy link

I think maybe it need more clear way to set and get fields from storage

@sanchezweezer
Copy link

I'll try to fix this on weekend

@volkandkaya
Copy link

@sanchezweezer was you able to get it working? I'm close but having issues due to localforage being async.

I can get it kind of working but it won't read from cache if the page is refreshed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants