Zustand Persist Middleware: How to not reset expiry value on rehydrate

161 Views Asked by At

I am trying to create a store with an automated timeout as indicated by an "expiry" value.

Here is the code snippet from my attempt:

import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";
import { addSeconds } from "date-fns";

import type { StateStorage } from "zustand/middleware";

type Sample = {
   id: number | string;
};

type SampleStore = {
   sample: Sample | null;
   setSample: (sample: Sample | null) => void;
};

const SAMPLE_TTL_SECS = 10;

const storage: StateStorage = {
   getItem: (name) => {
      const strItem = localStorage.getItem(name);

      if (!strItem) return null;

      const item = JSON.parse(strItem);

      if (new Date().getTime() > item.expiry) {
         localStorage.removeItem(name);

         return null;
      }

      return item.value;
   },
   setItem: (name, value) => {
      const item = {
         value,
         expiry: addSeconds(new Date(), SAMPLE_TTL_SECS).getTime(),
      };

      const strItem = JSON.stringify(item);

      localStorage.setItem(name, strItem);
   },
   removeItem: (name) => localStorage.removeItem(name),
};

export const useSampleStore = create<SampleStore>()(
   persist(
      (set) => ({
         sample: null,
         setSample: (sample) => set(() => ({ sample })),
      }),
      {
         name: "sample-storage",
         storage: createJSONStorage(() => storage),
      }
   )
);

The expiry of the related state is perfectly fine, however, there seems to be a problem during rehydration. Every time the app rehydrates the store, a new expiry value is being saved, thus recalculating the ttl of the current state. Is it possible to rehydrate the state while persisting the expiry value?

0

There are 0 best solutions below