{"version":3,"file":"index.modern.mjs","sources":["../src/useChromeStorage.js","../src/storage.js","../src/createChromeStorageStateHook.js","../src/index.js"],"sourcesContent":["import {useCallback, useEffect, useState} from 'react';\nimport {storage} from './storage';\n\n\n/**\n * Basic hook for storage\n * @param {string} key\n * @param {*} initialValue\n * @param {'local'|'sync'|'session'} storageArea\n * @returns {[*, function(*= any): void, boolean, string, boolean]}\n */\nexport default function useChromeStorage(key, initialValue, storageArea) {\n    const [INITIAL_VALUE] = useState(() => {\n        return typeof initialValue === 'function' ? initialValue() : initialValue;\n    });\n    const [STORAGE_AREA] = useState(storageArea);\n    const [state, setState] = useState(INITIAL_VALUE);\n    const [isPersistent, setIsPersistent] = useState(true);\n    const [error, setError] = useState('');\n    const [isInitialStateResolved, setIsInitialStateResolved] = useState(false);\n\n    useEffect(() => {\n        storage.get(key, INITIAL_VALUE, STORAGE_AREA)\n            .then(res => {\n                setState(res);\n                setIsPersistent(true);\n                setError('');\n            })\n            .catch(error => {\n                setIsPersistent(false);\n                setError(error);\n            })\n            .finally(() => {\n                setIsInitialStateResolved(true);\n            });\n    }, [key, INITIAL_VALUE, STORAGE_AREA]);\n\n    const updateValue = useCallback((newValue) => {\n        const toStore = typeof newValue === 'function' ? newValue(state) : newValue;\n        storage.set(key, toStore, STORAGE_AREA)\n            .then(() => {\n                setIsPersistent(true);\n                setError('');\n            })\n            .catch(error => {\n                // set newValue to local state because chrome.storage.onChanged won't be fired in error case\n                setState(toStore);\n                setIsPersistent(false);\n                setError(error);\n            });\n    }, [STORAGE_AREA, key, state]);\n\n    useEffect(() => {\n        const onChange = (changes, areaName) => {\n            if (areaName === STORAGE_AREA && key in changes) {\n                const change = changes[key]; \n                const isValueStored = 'newValue' in change;\n                // only set the new value if it's actually stored (otherwise it'll just set undefined)\n                if (isValueStored) {\n                    setState(change.newValue);\n                } else {\n                    setState(INITIAL_VALUE);\n                }\n                setIsPersistent(isValueStored);\n                setError('');\n            }\n        };\n        chrome.storage.onChanged.addListener(onChange);\n        return () => {\n            chrome.storage.onChanged.removeListener(onChange);\n        };\n    }, [key, STORAGE_AREA]);\n\n    return [state, updateValue, isPersistent, error, isInitialStateResolved];\n}\n","export const storage = {\n    get: (key, defaultValue, storageArea) => {\n        const keyObj = defaultValue === undefined ? key : {[key]: defaultValue};\n        return new Promise((resolve, reject) => {\n            chrome.storage[storageArea].get(keyObj, items => {\n                const error = chrome.runtime.lastError;\n                if (error) return reject(error);\n                resolve(items[key]);\n            });\n        });\n    },\n    set: (key, value, storageArea) => {\n        return new Promise((resolve, reject) => {\n            chrome.storage[storageArea].set({[key]: value}, () => {\n                const error = chrome.runtime.lastError;\n                error ? reject(error) : resolve();\n            });\n        });\n    },\n};\n","import {useCallback, useEffect} from 'react';\nimport useChromeStorage from './useChromeStorage';\n\n\nexport default function createChromeStorageStateHook(key, initialValue, storageArea) {\n    const consumers = [];\n\n    return function useCreateChromeStorageHook() {\n        const [value, setValue, isPersistent, error, isInitialStateResolved] = useChromeStorage(\n            key,\n            initialValue,\n            storageArea,\n        );\n\n        const setValueAll = useCallback((newValue) => {\n            for (const consumer of consumers) {\n                consumer(newValue);\n            }\n        }, []);\n\n        useEffect(() => {\n            consumers.push(setValue);\n            return () => {\n                consumers.splice(consumers.indexOf(setValue), 1);\n            };\n        }, [setValue]);\n\n        return [value, setValueAll, isPersistent, error, isInitialStateResolved];\n    };\n}\n\n","import createChromeStorageStateHook from './createChromeStorageStateHook';\nimport useChromeStorage from './useChromeStorage';\n\n\n/**\n * Hook which will use `chrome.storage.local` to persist state.\n *\n * @param {string} key - they key name in chrome's storage. Nested keys not supported\n * @param {*} [initialValue] - default value to use\n * @returns {[any, (value: any) => void, boolean, string]} - array of\n *      stateful `value`,\n *      function to update this `value`,\n *      `isPersistent` - will be `false` if error occurred during reading/writing chrome.storage,\n *      `error` - will contain error appeared in storage. if isPersistent is true, there will be an empty string\n *      `isInitialStateResolved` - will set to `true` once `initialValue` will be replaced with stored in chrome.storage\n */\nfunction useChromeStorageLocal(key, initialValue) {\n    return useChromeStorage(key, initialValue, 'local');\n}\n\n/**\n * Hook which will use `chrome.storage.sync` to persist state.\n *\n * @param {string} key - they key name in chrome's storage. Nested keys not supported\n * @param {*} [initialValue] - default value to use\n * @returns {[any, (value: any) => void, boolean, string, boolean]} - array of\n *      stateful `value`,\n *      function to update this `value`,\n *      `isPersistent` - will be `false` if error occurred during reading/writing chrome.storage,\n *      `error` - will contain error appeared in storage. if isPersistent is true, there will be an empty string\n *      `isInitialStateResolved` - will set to `true` once `initialValue` will be replaced with stored in chrome.storage\n */\nfunction useChromeStorageSync(key, initialValue) {\n    return useChromeStorage(key, initialValue, 'sync');\n}\n\n/**\n * Hook which will use `chrome.storage.session` to persist state.\n * By default, `chrome.storage.session` not exposed to content scripts,\n * but this behavior can be changed by setting chrome.storage.session.setAccessLevel() in the background script.\n * https://developer.chrome.com/docs/extensions/reference/storage/#method-StorageArea-setAccessLevel\n *\n * @param {string} key - they key name in chrome's storage. Nested keys not supported\n * @param {*} [initialValue] - default value to use\n * @returns {[any, (value: any) => void, boolean, string, boolean]} - array of\n *      stateful `value`,\n *      function to update this `value`,\n *      `isPersistent` - will be `false` if error occurred during reading/writing chrome.storage,\n *      `error` - will contain error appeared in storage. if isPersistent is true, there will be an empty string\n *      `isInitialStateResolved` - will set to `true` once `initialValue` will be replaced with stored in chrome.storage\n */\nfunction useChromeStorageSession(key, initialValue) {\n    return useChromeStorage(key, initialValue, 'session');\n}\n\n/**\n * Use to create state with chrome.storage.local.\n * Useful if you want to reuse same state across components and/or context (like in popup, content script, background pages)\n *\n * @param {string} key - they key name in chrome's storage. Nested keys are not supported\n * @param {*} [initialValue] - default value to use\n * @returns {function(): [any, (value: any) => void, boolean, string, boolean]}\n *          - useChromeStorageLocal hook which may be used across extension's components/pages\n */\nfunction createChromeStorageStateHookLocal(key, initialValue) {\n    return createChromeStorageStateHook(key, initialValue, 'local');\n}\n\n/**\n * Use to create state with chrome.storage.sync.\n * Useful if you want to reuse same state across components and/or context (like in popup, content script, background pages)\n *\n * @param {string} key - they key name in chrome's storage. Nested keys are not supported\n * @param {*} [initialValue] - default value to use\n * @returns {function(): [any, (value: any) => void, boolean, string, boolean]}\n *          - useChromeStorageSync hook which may be used across extension's components/pages\n */\nfunction createChromeStorageStateHookSync(key, initialValue) {\n    return createChromeStorageStateHook(key, initialValue, 'sync');\n}\n\n/**\n * Use to create state with chrome.storage.session.\n * Useful if you want to reuse same state across components and/or context (like in popup, content script, background pages)\n * By default, `chrome.storage.session` not exposed to content scripts,\n * but this behavior can be changed by setting chrome.storage.session.setAccessLevel() in the background script.\n * https://developer.chrome.com/docs/extensions/reference/storage/#method-StorageArea-setAccessLevel\n *\n * @param {string} key - they key name in chrome's storage. Nested keys are not supported\n * @param {*} [initialValue] - default value to use\n * @returns {function(): [any, (value: any) => void, boolean, string, boolean]}\n *          - useChromeStorageSession hook which may be used across extension's components/pages\n */\nfunction createChromeStorageStateHookSession(key, initialValue) {\n    return createChromeStorageStateHook(key, initialValue, 'session');\n}\n\nexport {\n    useChromeStorageLocal,\n    useChromeStorageSync,\n    useChromeStorageSession,\n    createChromeStorageStateHookLocal,\n    createChromeStorageStateHookSync,\n    createChromeStorageStateHookSession,\n};\n"],"names":["useChromeStorage","key","initialValue","storageArea","INITIAL_VALUE","useState","STORAGE_AREA","state","setState","isPersistent","setIsPersistent","error","setError","isInitialStateResolved","setIsInitialStateResolved","useEffect","get","defaultValue","keyObj","undefined","Promise","resolve","reject","chrome","storage","items","runtime","lastError","then","res","catch","finally","updateValue","useCallback","newValue","toStore","set","value","onChange","changes","areaName","change","isValueStored","onChanged","addListener","removeListener","createChromeStorageStateHook","consumers","setValue","setValueAll","consumer","push","splice","indexOf","useChromeStorageLocal","useChromeStorageSync","useChromeStorageSession","createChromeStorageStateHookLocal","createChromeStorageStateHookSync","createChromeStorageStateHookSession"],"mappings":"0EAWwBA,EAAiBC,EAAKC,EAAcC,GACxD,MAAOC,GAAiBC,EAAS,IACE,mBAAjBH,EAA8BA,IAAiBA,IAE1DI,GAAgBD,EAASF,IACzBI,EAAOC,GAAYH,EAASD,IAC5BK,EAAcC,GAAmBL,GAAS,IAC1CM,EAAOC,GAAYP,EAAS,KAC5BQ,EAAwBC,GAA6BT,GAAS,GAErEU,EAAU,KCpBLC,EAACf,EAAKgB,EAAcd,KACrB,MAAMe,OAA0BC,IAAjBF,EAA6BhB,EAAM,CAACA,CAACA,GAAMgB,GAC1D,WAAWG,QAAQ,CAACC,EAASC,KACzBC,OAAOC,QAAQrB,GAAaa,IAAIE,EAAQO,IACpC,MAAMd,EAAQY,OAAOG,QAAQC,UAC7B,GAAIhB,EAAO,OAAOW,EAAOX,GACzBU,EAAQI,EAAMxB,OAErB,EDaDuB,CAAYvB,EAAKG,EAAeE,GAC3BsB,KAAKC,IACFrB,EAASqB,GACTnB,GAAgB,GAChBE,EAAS,MAEZkB,MAAMnB,IACHD,GAAgB,GAChBE,EAASD,KAEZoB,QAAQ,KACLjB,GAA0B,MAEnC,CAACb,EAAKG,EAAeE,IAExB,MAAM0B,EAAcC,EAAaC,IAC7B,MAAMC,EAA8B,mBAAbD,EAA0BA,EAAS3B,GAAS2B,EC3BlEE,EAACnC,EAAKoC,EAAOlC,QACHiB,QAAQ,CAACC,EAASC,KACzBC,OAAOC,QAAQrB,GAAaiC,IAAI,CAACnC,CAACA,GAAMoC,GAAQ,KAC5C,MAAM1B,EAAQY,OAAOG,QAAQC,UAC7BhB,EAAQW,EAAOX,GAASU,QDwBhCG,CAAYvB,EAAKkC,EAAS7B,GACrBsB,KAAK,KACFlB,GAAgB,GAChBE,EAAS,MAEZkB,MAAMnB,IAEHH,EAAS2B,GACTzB,GAAgB,GAChBE,EAASD,MAElB,CAACL,EAAcL,EAAKM,IAuBvB,OArBAQ,EAAU,KACN,MAAMuB,EAAWA,CAACC,EAASC,KACvB,GAAIA,IAAalC,GAAgBL,KAAOsC,EAAS,CAC7C,MAAME,EAASF,EAAQtC,GACjByC,EAAgB,aAAcD,EAGhCjC,EADAkC,EACSD,EAAOP,SAEP9B,GAEbM,EAAgBgC,GAChB9B,EAAS,GACb,GAGJ,OADAW,OAAOC,QAAQmB,UAAUC,YAAYN,GAC9B,KACHf,OAAOC,QAAQmB,UAAUE,eAAeP,GAC5C,EACD,CAACrC,EAAKK,IAEF,CAACC,EAAOyB,EAAavB,EAAcE,EAAOE,EACrD,UEtEwBiC,EAA6B7C,EAAKC,EAAcC,GACpE,MAAM4C,EAAY,GAElB,kBACI,MAAOV,EAAOW,EAAUvC,EAAcE,EAAOE,GAA0Bb,EACnEC,EACAC,EACAC,GAGE8C,EAAchB,EAAaC,IAC7B,IAAK,MAAMgB,KAAYH,EACnBG,EAAShB,EACb,EACD,IASH,OAPAnB,EAAU,KACNgC,EAAUI,KAAKH,GACR,KACHD,EAAUK,OAAOL,EAAUM,QAAQL,GAAW,KAEnD,CAACA,IAEG,CAACX,EAAOY,EAAaxC,EAAcE,EAAOE,EACrD,CACJ,CCbA,SAASyC,EAAsBrD,EAAKC,GAChC,OAAOF,EAAiBC,EAAKC,EAAc,QAC/C,CAcA,SAASqD,EAAqBtD,EAAKC,GAC/B,OAAOF,EAAiBC,EAAKC,EAAc,OAC/C,CAiBA,SAASsD,EAAwBvD,EAAKC,GAClC,OAAOF,EAAiBC,EAAKC,EAAc,UAC/C,CAWA,SAASuD,EAAkCxD,EAAKC,GAC5C,OAAO4C,EAA6B7C,EAAKC,EAAc,QAC3D,CAWA,SAASwD,EAAiCzD,EAAKC,GAC3C,OAAO4C,EAA6B7C,EAAKC,EAAc,OAC3D,CAcA,SAASyD,EAAoC1D,EAAKC,GAC9C,OAAO4C,EAA6B7C,EAAKC,EAAc,UAC3D"}