vue-persistent-storage-manager
Version:
Vue plugin that wraps the StorageManager API and provides the state of the persistent-storage permission alongside a storage estimate.
1 lines • 5.82 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["// oxlint-disable typescript/unbound-method\nimport type { PluginFunction } from 'vue'\nimport Vue from 'vue'\n\n/**\n * Options for the VuePersistentStorageManager plugin.\n */\nexport interface PluginOptions {\n /**\n * If true, localStorage.setItem and localStorage.removeItem will be replaced with custom functions.\n */\n watchStorage: boolean\n}\n\nconst defaultOptions: PluginOptions = {\n watchStorage: false,\n}\n\n/**\n * Wrapper for the StorageManager API. Provides the state of the persistent-storage permission alongside a storage estimate.\n */\nexport class VuePersistentStorageManager {\n /**\n * Indicates that the StorageManager API is available.\n */\n public readonly isAvailable: boolean =\n typeof navigator !== 'undefined' && navigator?.storage?.persist !== undefined\n\n /**\n * Contains storage quota and usage information.\n */\n public readonly storageEstimate: StorageEstimate = {}\n\n private _isPersistent = false\n\n /**\n * Installs a VuePersistentStorageManager as a Vue plugin.\n */\n public static install: PluginFunction<PluginOptions> = (_Vue, options) => {\n const pluginOptions: PluginOptions = { ...defaultOptions, ...options }\n const storageManager = Vue.observable(new VuePersistentStorageManager())\n if (pluginOptions.watchStorage) {\n storageManager._modifyLocalStorageFunctions()\n }\n _Vue.prototype.$storageManager = storageManager\n _Vue.prototype.$storageEstimate = storageManager.storageEstimate\n }\n\n /**\n * Creates a new VuePersistentStorageManager instance.\n */\n public constructor() {\n if (!this.isAvailable) {\n return\n }\n this._refreshIsPersistent()\n this._refreshStorageEstimate()\n void navigator.permissions\n ?.query({ name: 'persistent-storage' })\n ?.then((persistentStoragePermission) => {\n persistentStoragePermission.onchange = () => this._refreshIsPersistent()\n })\n window.addEventListener('storage', () => {\n this._refreshStorageEstimate()\n })\n }\n\n /**\n * Indicates that persistence of localStorage has been granted.\n */\n public get isPersistent(): boolean {\n return this._isPersistent\n }\n\n /**\n * Requests persistence of localStorage.\n * @returns a Promise that resolves to true if permission has been granted.\n */\n public requestPersistentStorage(): Promise<boolean> {\n if (!this.isAvailable) {\n return Promise.resolve(false)\n }\n return navigator.storage.persist().then((persisted) => {\n this._isPersistent = persisted\n return persisted\n })\n }\n\n private _refreshIsPersistent() {\n void navigator.storage.persisted().then((persisted) => (this._isPersistent = persisted))\n }\n\n private _refreshStorageEstimate() {\n void navigator.storage.estimate().then(({ quota, usage }) => {\n Vue.set(this.storageEstimate, 'quota', quota)\n Vue.set(this.storageEstimate, 'usage', usage)\n })\n }\n\n private _modifyLocalStorageFunctions(): void {\n if (typeof localStorage === 'undefined') {\n return\n }\n // oxlint-disable-next-line no-this-alias\n const self = this\n if (typeof localStorage.originalSetItem === 'undefined') {\n localStorage.originalSetItem = localStorage.setItem\n }\n const setItem = localStorage.setItem\n localStorage.setItem = function (...args) {\n setItem.apply(this, args)\n self._refreshStorageEstimate()\n }\n if (typeof localStorage.originalRemoveItem === 'undefined') {\n localStorage.originalRemoveItem = localStorage.removeItem\n }\n const removeItem = localStorage.removeItem\n localStorage.removeItem = function (...args) {\n removeItem.apply(this, args)\n self._refreshStorageEstimate()\n }\n }\n}\n\ndeclare module 'vue/types/vue' {\n interface Vue {\n /**\n * Wrapper for the StorageManager API. Provides the state of the persistent-storage permission alongside a storage estimate.\n */\n $storageManager: VuePersistentStorageManager\n /**\n * Contains storage quota and usage information.\n */\n $storageEstimate: StorageEstimate\n }\n}\n\ndeclare global {\n interface Storage {\n originalSetItem?: ((key: string, value: string) => void) | undefined\n originalRemoveItem?: ((key: string) => void) | undefined\n }\n}\n"],"mappings":";;;AAcA,MAAM,iBAAgC,EACpC,cAAc,OACf;;;;AAKD,IAAa,8BAAb,MAAa,4BAA4B;;;;CAIvC,AAAgB,cACd,OAAO,cAAc,eAAe,WAAW,SAAS,YAAY;;;;CAKtE,AAAgB,kBAAmC,EAAE;CAErD,AAAQ,gBAAgB;;;;CAKxB,OAAc,WAA0C,MAAM,YAAY;EACxE,MAAM,gBAA+B;GAAE,GAAG;GAAgB,GAAG;GAAS;EACtE,MAAM,iBAAiB,IAAI,WAAW,IAAI,6BAA6B,CAAC;AACxE,MAAI,cAAc,aAChB,gBAAe,8BAA8B;AAE/C,OAAK,UAAU,kBAAkB;AACjC,OAAK,UAAU,mBAAmB,eAAe;;;;;CAMnD,AAAO,cAAc;AACnB,MAAI,CAAC,KAAK,YACR;AAEF,OAAK,sBAAsB;AAC3B,OAAK,yBAAyB;AAC9B,EAAK,UAAU,aACX,MAAM,EAAE,MAAM,sBAAsB,CAAC,EACrC,MAAM,gCAAgC;AACtC,+BAA4B,iBAAiB,KAAK,sBAAsB;IACxE;AACJ,SAAO,iBAAiB,iBAAiB;AACvC,QAAK,yBAAyB;IAC9B;;;;;CAMJ,IAAW,eAAwB;AACjC,SAAO,KAAK;;;;;;CAOd,AAAO,2BAA6C;AAClD,MAAI,CAAC,KAAK,YACR,QAAO,QAAQ,QAAQ,MAAM;AAE/B,SAAO,UAAU,QAAQ,SAAS,CAAC,MAAM,cAAc;AACrD,QAAK,gBAAgB;AACrB,UAAO;IACP;;CAGJ,AAAQ,uBAAuB;AAC7B,EAAK,UAAU,QAAQ,WAAW,CAAC,MAAM,cAAe,KAAK,gBAAgB,UAAW;;CAG1F,AAAQ,0BAA0B;AAChC,EAAK,UAAU,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,YAAY;AAC3D,OAAI,IAAI,KAAK,iBAAiB,SAAS,MAAM;AAC7C,OAAI,IAAI,KAAK,iBAAiB,SAAS,MAAM;IAC7C;;CAGJ,AAAQ,+BAAqC;AAC3C,MAAI,OAAO,iBAAiB,YAC1B;EAGF,MAAM,OAAO;AACb,MAAI,OAAO,aAAa,oBAAoB,YAC1C,cAAa,kBAAkB,aAAa;EAE9C,MAAM,UAAU,aAAa;AAC7B,eAAa,UAAU,SAAU,GAAG,MAAM;AACxC,WAAQ,MAAM,MAAM,KAAK;AACzB,QAAK,yBAAyB;;AAEhC,MAAI,OAAO,aAAa,uBAAuB,YAC7C,cAAa,qBAAqB,aAAa;EAEjD,MAAM,aAAa,aAAa;AAChC,eAAa,aAAa,SAAU,GAAG,MAAM;AAC3C,cAAW,MAAM,MAAM,KAAK;AAC5B,QAAK,yBAAyB"}