Untitled

 avatar
unknown
plain_text
a month ago
3.3 kB
3
Indexable
import { atom } from 'jotai';
import { SecureStorageService } from '../services/secureStorage';

/**
 * Creates a persisted atom that automatically saves its value to SecureStore
 * @param key The key to use for storage
 * @param initialValue The initial value of the atom
 * @returns A writable atom that persists its value
 */
export function createPersistedAtom<T>(
  key: string,
  initialValue: T
) {
  // Create a base atom with the initial value
  const baseAtom = atom<T>(initialValue);
  
  // Create a derived atom that handles persistence
  const derivedAtom = atom(
    // Read function
    async (get) => {
      try {
        // Try to get the value from secure storage
        const storedValue = await SecureStorageService.getItem(key);
        
        // If there's a stored value, parse and return it
        if (storedValue) {
          return JSON.parse(storedValue) as T;
        }
        
        // Otherwise, return the initial value
        return get(baseAtom);
      } catch (error) {
        console.error(`Error reading persisted atom ${key}:`, error);
        return get(baseAtom);
      }
    },
    // Write function
    async (get, set, update: T) => {
      try {
        // Update the base atom
        set(baseAtom, update);
        
        // Persist the value to secure storage
        await SecureStorageService.saveItem(key, JSON.stringify(update));
      } catch (error) {
        console.error(`Error persisting atom ${key}:`, error);
      }
    }
  );
  
  return derivedAtom;
}

/**
 * Creates a persisted atom that automatically saves its value to SecureStore
 * This version is for primitive values (string, number, boolean)
 * @param key The key to use for storage
 * @param initialValue The initial value of the atom
 * @returns A writable atom that persists its value
 */
export function createPersistedPrimitiveAtom<T extends string | number | boolean>(
  key: string,
  initialValue: T
) {
  // Create a base atom with the initial value
  const baseAtom = atom<T>(initialValue);
  
  // Create a derived atom that handles persistence
  const derivedAtom = atom(
    // Read function
    (get) => {
      return get(baseAtom);
    },
    // Write function
    async (get, set, update: T) => {
      try {
        // Update the base atom
        set(baseAtom, update);
        
        // Persist the value to secure storage
        await SecureStorageService.saveItem(key, String(update));
      } catch (error) {
        console.error(`Error persisting atom ${key}:`, error);
      }
    }
  );
  
  // Initialize the atom by loading from storage
  (async () => {
    try {
      const storedValue = await SecureStorageService.getItem(key);
      if (storedValue !== null) {
        // Parse the value based on its type
        let parsedValue: T;
        if (typeof initialValue === 'number') {
          parsedValue = Number(storedValue) as T;
        } else if (typeof initialValue === 'boolean') {
          parsedValue = (storedValue === 'true') as unknown as T;
        } else {
          parsedValue = storedValue as T;
        }
        
        // Set the base atom with the loaded value
        baseAtom.init = parsedValue;
      }
    } catch (error) {
      console.error(`Error initializing persisted atom ${key}:`, error);
    }
  })();
  
  return derivedAtom;
}
Editor is loading...
Leave a Comment