Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/persistence / src / OneStorage.ts
Size: Mime:
/**
 * @todo replace oneStorage everywhere
 */
import indexdb from './adapters/indexdb'
import ls from './adapters/local-storage'
import inMemory from './adapters/in-memory'
import { Serializable } from './deps/stringify'

const IS_BROWSER = typeof window === 'object'
const HAS_INDEX_DB = IS_BROWSER && 'indexedDB' in window

/**
 * keys, values...
 * @alias OmniStorage
 *
 * @todo only use the adapters (means use this.ls > ls)
 *       so they can be overwritten
 */
class OneStorage {
  inMemory: typeof inMemory
  indexdb: typeof indexdb
  ls: typeof ls
  constructor() {
    this.inMemory = inMemory
    this.indexdb = indexdb
    this.ls = ls
  }
  // parse when reading back out of ls...?
  get<Value extends Serializable = Serializable>(key: string): Value {
    if (inMemory.has(key) === true) {
      return inMemory.get(key)
    }
    if (ls.has(key) === true) {
      return ls.get(key)
    }
    // not sure this is needed
    const existing = inMemory.get(key)

    /**
     * @note - very weird to do a set on a get
     * @todo - this was here for good reason, but not good for tests
     */
    // if (HAS_INDEX_DB) {
    //   indexdb.get(key).then(saved => {
    //     if (existing !== saved) {
    //       inMemory.set(key, saved)
    //     }
    //   })
    // }

    return existing
  }

  /**
   * @todo is it faster to "graphql-client-cache" ignore if it always fills?
   */
  set(key: string, value: Serializable) {
    // store as string for graphql? perf?
    // const final = isString(value) ? JSON.parse(value) : value
    // return indexdb.set(key, final)
    // @note @important - we start indexdb transaction first, it's async
    const resolving = HAS_INDEX_DB
      ? indexdb.set(key, value)
      : Promise.resolve(-42)

    // not putting it in ls, took 1s
    if (key !== 'graphql-client-cache') {
      ls.set(key, value)
    }
    inMemory.set(key, value)

    return resolving
    // indexdb.set(key, value)
    // if (isObj(value)) {
    //   indexdb.set(key, JSON.stringify(value))
    // } else {
    //   indexdb.set(key, value)
    // }
  }
  has(key: string) {
    return !!this.get(key)
  }
  remove(key: string) {
    const resolving = HAS_INDEX_DB
      ? indexdb.delete(key)
      : Promise.resolve(-42)

    inMemory.delete(key)
    ls.remove(key)

    return resolving
  }
  clear() {
    const resolving = HAS_INDEX_DB
      ? indexdb.clear()
      : Promise.resolve(-42)

    inMemory.clear()
    ls.clear()

    return resolving
  }

  // async size() {
  //   const keys = await indexdb.keys()
  //   return keys.length
  // }
  get length(): number {
    return inMemory.size || ls.length || 0
  }
}
// eslint-disable-next-line
OneStorage.prototype['delete'] = OneStorage.prototype.remove
OneStorage.prototype['removeItem'] = OneStorage.prototype.remove
OneStorage.prototype['getItem'] = OneStorage.prototype.get
OneStorage.prototype['setItem'] = OneStorage.prototype.set
OneStorage.prototype['hasItem'] = OneStorage.prototype.has

export { OneStorage }
export default OneStorage