diff --git a/desktop/flipper-plugin-core/src/index.tsx b/desktop/flipper-plugin-core/src/index.tsx index 400804791..af5da2683 100644 --- a/desktop/flipper-plugin-core/src/index.tsx +++ b/desktop/flipper-plugin-core/src/index.tsx @@ -54,6 +54,8 @@ export {createDataSource} from './state/createDataSource'; export { createState, + _setAtomPersistentStorage, + AtomPersistentStorage, Atom, isAtom, ReadOnlyAtom as _ReadOnlyAtom, diff --git a/desktop/flipper-plugin-core/src/state/atom.tsx b/desktop/flipper-plugin-core/src/state/atom.tsx index b4ba65730..9eeee7981 100644 --- a/desktop/flipper-plugin-core/src/state/atom.tsx +++ b/desktop/flipper-plugin-core/src/state/atom.tsx @@ -106,7 +106,7 @@ export function createState( options: StateOptions = {}, ): Atom { const atom = new AtomValue(initialValue); - if (options?.persistToLocalStorage) { + if (options?.persistToLocalStorage && atomStorage) { syncAtomWithLocalStorage(options, atom); } else { registerStorageAtom(options.persist, atom); @@ -114,12 +114,26 @@ export function createState( return atom; } +export interface AtomPersistentStorage { + getItem(key: string): string | null; + setItem(key: string, value: string): void; +} +let atomStorage: AtomPersistentStorage | undefined; +export function _setAtomPersistentStorage(newStorage: AtomPersistentStorage) { + atomStorage = newStorage; +} + function syncAtomWithLocalStorage(options: StateOptions, atom: AtomValue) { if (!options?.persist) { throw new Error( "The 'persist' option should be set when 'persistToLocalStorage' is set", ); } + if (!atomStorage) { + throw new Error( + "'atomStorage' is not implemented. Use 'setAtomPersistentStorage' to set AtomPersistentStorage implementation", + ); + } const pluginInstance = getCurrentPluginInstance(); if (!pluginInstance) { throw new Error( @@ -127,12 +141,12 @@ function syncAtomWithLocalStorage(options: StateOptions, atom: AtomValue) { ); } const storageKey = `flipper:${pluginInstance.definition.id}:atom:${options.persist}`; - const storedValue = window.localStorage.getItem(storageKey); + const storedValue = atomStorage.getItem(storageKey); if (storedValue != null) { atom.deserialize(JSON.parse(storedValue)); } atom.subscribe(() => { - window.localStorage.setItem(storageKey, JSON.stringify(atom.serialize())); + atomStorage!.setItem(storageKey, JSON.stringify(atom.serialize())); }); } diff --git a/desktop/flipper-plugin/src/__tests__/api.node.tsx b/desktop/flipper-plugin/src/__tests__/api.node.tsx index 3daf34b09..0af03ab3d 100644 --- a/desktop/flipper-plugin/src/__tests__/api.node.tsx +++ b/desktop/flipper-plugin/src/__tests__/api.node.tsx @@ -81,6 +81,7 @@ test('Correct top level API exposed', () => { expect(exposedTypes.sort()).toMatchInlineSnapshot(` Array [ "Atom", + "AtomPersistentStorage", "CrashLog", "CrashLogListener", "CreatePasteArgs", diff --git a/desktop/flipper-plugin/src/index.tsx b/desktop/flipper-plugin/src/index.tsx index bcaf0bfa5..0c71c42e7 100644 --- a/desktop/flipper-plugin/src/index.tsx +++ b/desktop/flipper-plugin/src/index.tsx @@ -7,6 +7,9 @@ * @format */ +import {_setAtomPersistentStorage} from 'flipper-plugin-core'; +_setAtomPersistentStorage(window.localStorage); + export * from 'flipper-plugin-core'; import styledImport from '@emotion/styled';