UNPKG

flipper-plugin

Version:

Flipper Desktop plugin SDK and components

109 lines 3.67 kB
"use strict"; /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format */ Object.defineProperty(exports, "__esModule", { value: true }); exports.useValue = exports.isAtom = exports.createState = exports.AtomValue = void 0; const react_1 = require("react"); const immer_1 = require("immer"); const PluginBase_1 = require("../plugin/PluginBase"); const shallowSerialization_1 = require("../utils/shallowSerialization"); (0, immer_1.enableMapSet)(); class AtomValue { constructor(initialValue) { this.listeners = []; this.value = initialValue; } get() { return this.value; } set(nextValue) { if (nextValue !== this.value) { const prevValue = this.value; this.value = nextValue; this.notifyChanged(prevValue); } } deserialize(value) { this.set((0, shallowSerialization_1.deserializeShallowObject)(value)); } serialize() { return (0, shallowSerialization_1.makeShallowSerializable)(this.get()); } update(recipe) { this.set((0, immer_1.produce)(this.value, recipe)); } notifyChanged(prevValue) { // TODO: add scheduling this.listeners.slice().forEach((l) => l(this.value, prevValue)); } subscribe(listener) { this.listeners.push(listener); return () => this.unsubscribe(listener); } unsubscribe(listener) { const idx = this.listeners.indexOf(listener); if (idx !== -1) { this.listeners.splice(idx, 1); } } } exports.AtomValue = AtomValue; function createState(initialValue = undefined, options = {}) { const atom = new AtomValue(initialValue); if (options?.persistToLocalStorage) { syncAtomWithLocalStorage(options, atom); } else { (0, PluginBase_1.registerStorageAtom)(options.persist, atom); } return atom; } exports.createState = createState; function syncAtomWithLocalStorage(options, atom) { if (!options?.persist) { throw new Error("The 'persist' option should be set when 'persistToLocalStorage' is set"); } const pluginInstance = (0, PluginBase_1.getCurrentPluginInstance)(); if (!pluginInstance) { throw new Error("The 'persistToLocalStorage' option cannot be used outside a plugin definition"); } const storageKey = `flipper:${pluginInstance.definition.id}:atom:${options.persist}`; const storedValue = window.localStorage.getItem(storageKey); if (storedValue != null) { atom.deserialize(JSON.parse(storedValue)); } atom.subscribe(() => { window.localStorage.setItem(storageKey, JSON.stringify(atom.serialize())); }); } function isAtom(value) { return value instanceof AtomValue; } exports.isAtom = isAtom; function useValue(atom, defaultValue) { const [localValue, setLocalValue] = (0, react_1.useState)( // TODO: Fix this the next time the file is edited. // eslint-disable-next-line @typescript-eslint/no-non-null-assertion atom ? atom.get() : defaultValue); (0, react_1.useEffect)(() => { if (!atom) { return; } // atom might have changed between mounting and effect setup // in that case, this will cause a re-render, otherwise not setLocalValue(atom.get()); atom.subscribe(setLocalValue); return () => { atom.unsubscribe(setLocalValue); }; }, [atom]); return localValue; } exports.useValue = useValue; //# sourceMappingURL=atom.js.map