Untitled

 avatar
unknown
plain_text
15 days ago
2.2 kB
4
Indexable
/**
 * 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);
  
  // Set up initialization when the atom is first used in a component
  baseAtom.onMount = (setValue) => {
    (async () => {
      try {
        const storedValue = await SecureStorageService.getItem(key);
        
        if (storedValue) {
          // Parse the stored value
          const parsedValue = JSON.parse(storedValue) as T;
          setValue(parsedValue);
          console.log(`Loaded persisted atom ${key} from storage`);
        } else {
          // No stored value, use initial value and save it
          setValue(initialValue);
          
          await SecureStorageService.saveItem(key, JSON.stringify(initialValue));
          console.log(`Initialized persisted atom ${key} with default value`);
        }
      } catch (error) {
        console.error(`Error initializing persisted atom ${key}:`, error);
        setValue(initialValue);
      }
    })();
  };
  
  // Create a derived atom that handles persistence
  const derivedAtom = atom(
    // Read function
    (get) => get(baseAtom),
    // Write function
    (get, set, update: T | ((prev: T) => T)) => {
      const currentValue = get(baseAtom);
      
      // Handle functional updates
      const nextValue = typeof update === 'function' 
        ? (update as ((prev: T) => T))(currentValue) 
        : update;
      
      // Only update if the value has changed
      // Note: For deep equality, you might want to add a dependency like lodash
      if (JSON.stringify(currentValue) !== JSON.stringify(nextValue)) {
        // Update the base atom
        set(baseAtom, nextValue);
        
        // Persist to secure storage (don't await to avoid blocking)
        SecureStorageService.saveItem(key, JSON.stringify(nextValue))
          .catch(error => console.error(`Error persisting atom ${key}:`, error));
      }
    }
  );
  
  return derivedAtom;
}
Editor is loading...
Leave a Comment