Cacher.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import type { Cache } from '@src/@types/Cache'
  2. const MAX_ITEMS = 100
  3. const DEFAULT_MAX_AGE = 30 * 60 * 1000 // 30 minutes
  4. const STORE = 'api-cacher'
  5. class Cacher {
  6. load(options: {
  7. key: string,
  8. maxAge?: number | null,
  9. }): any {
  10. const { key, maxAge } = options
  11. const storage: Cache = JSON.parse(localStorage.getItem(STORE) || '{}')
  12. const item = storage[key]
  13. if (!item) {
  14. return null
  15. }
  16. const createdAt = new Date(item.createdAt).getTime()
  17. const actualMaxAge = (maxAge || DEFAULT_MAX_AGE)
  18. if (new Date().getTime() - createdAt > actualMaxAge) {
  19. delete storage[key]
  20. localStorage.setItem(STORE, JSON.stringify(storage))
  21. return null
  22. }
  23. console.log(`%cFrom cache ${key}`, 'color: #777A8B', item.data)
  24. return item.data
  25. }
  26. save(options: {
  27. key: string,
  28. data: any,
  29. }) {
  30. const { key, data } = options
  31. const storage: Cache = JSON.parse(localStorage.getItem(STORE) || '{}')
  32. const keys = Object.keys(storage)
  33. if (keys.length >= MAX_ITEMS + 10) {
  34. keys.sort((a, b) => new Date(storage[a].createdAt)
  35. .getTime() - new Date(storage[b].createdAt).getTime())
  36. for (let i = 0; i <= keys.length - MAX_ITEMS; i += 1) {
  37. delete storage[keys[i]]
  38. }
  39. }
  40. storage[key] = {
  41. data,
  42. createdAt: new Date().toISOString(),
  43. }
  44. localStorage.setItem(STORE, JSON.stringify(storage))
  45. }
  46. remove(keyStartsWith: string) {
  47. const storage: Cache = JSON.parse(localStorage.getItem(STORE) || '{}')
  48. Object.keys(storage).forEach(key => {
  49. if (key.startsWith(keyStartsWith)) {
  50. delete storage[key]
  51. }
  52. })
  53. localStorage.setItem(STORE, JSON.stringify(storage))
  54. }
  55. }
  56. export default new Cacher()