{"version":3,"file":"safeLocalStorage.cjs","sources":["../../src/browser/safeLocalStorage.js"],"sourcesContent":["/*\nNotes and Limitations:\n    * The `fallbackStorage` object is not shared between multiple browser tabs / windows\n    * The `.key()` method does not utilize the `fallbackStorage` object, so that it can be as compatible to multiple browser tabs as possible\n    * The `.length` getter does not utilize the `fallbackStorage` object, so that it can be as compatible to multiple browser tabs as possible\n    * The `handleError.onError` function is not reset by `handleError.reset()`\n*/\n\nconst handleError = {\n    errorCount: 0,\n    firstError: null,\n    lastError: null,\n    onError: null\n\n    // avoidDeadCodeElimination: null // The purpose of `handleError.avoidDeadCodeElimination` is to set an accessed value to it for avoiding the code usage from being removed by a dead code elimination tool\n};\nhandleError.reset = () => {\n    handleError.errorCount = 0;\n    handleError.firstError = null;\n    handleError.lastError = null;\n    // Note: `handleError.onError` is not being reset\n\n    // handleError.avoidDeadCodeElimination = null;\n};\n\nconst recordError = function (err) {\n    handleError.errorCount++;\n\n    if (handleError.firstError === null) {\n        handleError.firstError = err;\n    }\n\n    handleError.lastError = err;\n\n    if (typeof handleError.onError === 'function') {\n        handleError.onError(err);\n    }\n};\n\nconst fallbackStorage = Object.create(null); // No inherited properties, like `toString`, `hasOwnProperty`, etc.\n\nconst safeLocalStorage = {\n    getItem: function (key) {\n        try {\n            const value = localStorage.getItem(key);\n\n            if (value !== null) {\n                return value;\n            }\n        } catch (err) {\n            recordError(err);\n        }\n\n        if (Object.prototype.hasOwnProperty.call(fallbackStorage, key)) {\n            // Note: Not doing a check for `fallbackStorage[key] === undefined` since that case should not occur in normal usage\n            return fallbackStorage[key];\n        }\n        return null;\n    },\n\n    setItem: function (key, value) {\n        try {\n            fallbackStorage[key] = String(value);\n            localStorage.setItem(key, value);\n        } catch (err) {\n            recordError(err);\n        }\n    },\n\n    removeItem: function (key) {\n        try {\n            delete fallbackStorage[key];\n            localStorage.removeItem(key);\n        } catch (err) {\n            recordError(err);\n        }\n    },\n\n    clear: function () {\n        try {\n            for (const key in fallbackStorage) {\n                delete fallbackStorage[key];\n            }\n            localStorage.clear();\n        } catch (err) {\n            recordError(err);\n        }\n    },\n\n    key: function (index) {\n        /*\n        // This approach isn't compatible with multiple browser tabs, hence, it's not being used\n        const computedIndex = Number(index) || 0;\n        const keys = Object.keys(fallbackStorage);\n        const key = keys[computedIndex] || null;\n        try {\n            // Here, we are not utilizing the value of `localStorage.key(index)`. We are just checking if localStorage is available for access without error\n            handleError.avoidDeadCodeElimination = localStorage.key(index);\n        } catch (err) {\n            recordError(err);\n        }\n        return key;\n        */\n\n        try {\n            const key = localStorage.key(index);\n            return key;\n        } catch (err) {\n            recordError(err);\n            return null;\n        }\n    },\n\n    get length() {\n        /*\n        // This approach isn't compatible with multiple browser tabs, hence, it's not being used\n        const fallbackStorageLength = Object.keys(fallbackStorage).length;\n        try {\n            // Here, we are not utilizing the value of `localStorage.length`. We are just checking if localStorage is available for access without error.\n            handleError.avoidDeadCodeElimination = localStorage.length;\n        } catch (err) {\n            recordError(err);\n        }\n        return fallbackStorageLength;\n        */\n\n        try {\n            return localStorage.length;\n        } catch (err) {\n            recordError(err);\n            return 0;\n        }\n    }\n};\n\nexport {\n    safeLocalStorage,\n    fallbackStorage,\n    handleError\n};\n"],"names":["handleError","errorCount","firstError","lastError","onError","recordError","err","fallbackStorage","Object","create","safeLocalStorage","getItem","key","value","localStorage","prototype","hasOwnProperty","call","setItem","String","removeItem","clear","index","length"],"mappings":";AAQK,MAACA,YAAc,CAChBC,WAAY,EACZC,WAAY,KACZC,UAAW,KACXC,QAAS,KAIbJ,MAAoB,KAChBA,YAAYC,WAAa;AACzBD,YAAYE,WAAa;AACzBF,YAAYG,UAAY,OAMtBE,YAAc,SAAUC,KAC1BN,YAAYC;AAEmB,OAA3BD,YAAYE,aACZF,YAAYE,WAAaI;AAG7BN,YAAYG,UAAYG;AAEW,mBAAxBN,YAAYI,SACnBJ,YAAYI,QAAQE,IAE5B,EAEMC,gBAAkBC,OAAOC,OAAO,MAEhCC,iBAAmB,CACrBC,QAAS,SAAUC,KACf,IACI,MAAMC,MAAQC,aAAaH,QAAQC;AAEnC,GAAc,OAAVC,MACA,OAAOA,KAEf,CAAE,MAAOP,KACLD,YAAYC,IAChB,CAEA,OAAIE,OAAOO,UAAUC,eAAeC,KAAKV,gBAAiBK,KAE/CL,gBAAgBK,KAEpB,IACX,EAEAM,QAAS,SAAUN,IAAKC,OACpB,IACIN,gBAAgBK,KAAOO,OAAON;AAC9BC,aAAaI,QAAQN,IAAKC,MAC9B,CAAE,MAAOP,KACLD,YAAYC,IAChB,CACJ,EAEAc,WAAY,SAAUR,KAClB,WACWL,gBAAgBK;AACvBE,aAAaM,WAAWR,IAC5B,CAAE,MAAON,KACLD,YAAYC,IAChB,CACJ,EAEAe,MAAO,WACH,IACI,IAAK,MAAMT,OAAOL,uBACPA,gBAAgBK;AAE3BE,aAAaO,OACjB,CAAE,MAAOf,KACLD,YAAYC,IAChB,CACJ,EAEAM,IAAK,SAAUU,OAeX,IAEI,OADYR,aAAaF,IAAIU,MAEjC,CAAE,MAAOhB,KACLD,YAAYC;AACZ,OAAO,IACX,CACJ,EAEA,UAAIiB,GAaA,IACI,OAAOT,aAAaS,MACxB,CAAE,MAAOjB,KACLD,YAAYC;AACZ,OAAO,CACX,CACJ;;;"}