Skip to content

Instantly share code, notes, and snippets.

@dragon-fish
Last active March 10, 2023 18:01
Show Gist options
  • Save dragon-fish/a3f46e3c91e577b2d924b79286b2b8b8 to your computer and use it in GitHub Desktop.
Save dragon-fish/a3f46e3c91e577b2d924b79286b2b8b8 to your computer and use it in GitHub Desktop.
ObjectStorage.ts
/**
* ObjectStorage
* @desc JSON localStorage with auto cache
*
* @author Dragon-Fish <dragon-fish@qq.com>
* @license MIT
*/
export class ObjectStorage<T extends any> {
constructor(readonly name: string, readonly maxAge = 0) {}
getItem(): T | null {
if (this.isExpired) {
return null
}
const raw = this.cacheData
if (!raw) return null
try {
return JSON.parse(raw)
} catch (e) {
return null
}
}
setItem(data: T) {
localStorage.setItem(`${this.name}/data`, JSON.stringify(data))
localStorage.setItem(`${this.name}/time`, Date.now() + '')
return this
}
get cacheData() {
return localStorage.getItem(`${this.name}/data`)
}
get cacheTime() {
const time = +(localStorage.getItem(`${this.name}/time`) || '0')
return isNaN(time) ? 0 : time
}
get isExpired() {
return Date.now() >= this.cacheTime + this.maxAge
}
}
@dragon-fish
Copy link
Author

dragon-fish commented Mar 10, 2023

Example

A data request function. Comes with 10 minutes of local caching.

async function fetchData(): Promise<{ msg: string }> {
  const store = new ObjectStorage<{ msg: string }>('MyStore', 10 * 60 * 1000)
  const cache = store.getItem()
  if (cache) {
    return cache
  }
  return fetch('/api')
    .then((data) => data.json())
    .then((json) => {
      store.setItem(json)
      return json
    })
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment