diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac67caa --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +demo +test +/index.html +jsconfig.json \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..ed2d760 --- /dev/null +++ b/.npmignore @@ -0,0 +1,33 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +demo +dist +test +index.html +jsconfig.json \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9611c88 --- /dev/null +++ b/README.md @@ -0,0 +1,99 @@ +# Pinia Storage + +![npm license](https://img.shields.io/npm/l/@ctechhindi/Pinia-Storage.svg) +![npm download](https://img.shields.io/npm/dm/@ctechhindi/Pinia-Storage.svg) +![GitHub top language](https://img.shields.io/github/languages/top/ctechhindi/Pinia-Storage.svg) +![GitHub issues](https://img.shields.io/github/issues/ctechhindi/Pinia-Storage.svg) +[![npm package](https://img.shields.io/npm/v/@ctechhindi/Pinia-Storage.svg)](https://www.npmjs.com/package/@ctechhindi/Pinia-Storage) + +> A infinite progress bar for vue 3 + +- [GitHub](https://github.com/ctechhindi/Pinia-Storage) + +## Requirements + +- Vue.js `^3.0.0` + +## Installation + +### npm + +``` +npm i @ctechhindi/Pinia-Storage +``` + +## Usage + +**`main.js`** + +```js +import piniaStorage from "@ctechhindi/pinia-storage"; +const pinia = createPinia(); +pinia.use(piniaStorage); +``` + +**`\stores\{sites}-store.js`** + +```js +import { defineStore } from "pinia"; + +export const useUsersStore = defineStore({ + id: "users-store", + state: () => ({ + name: { + first: "", + last: "", + }, + }), + conserve: { + enabled: true, + strategies: [ + { storage: localStorage, states: ["name"] }, // Save custom state + // { storage: localStorage, }, // Save all state + // { storage: sessionStorage, states: ['name'] }, + ], + }, + getters: {}, + actions: {}, +}); +``` + +### Custom LocalStorage + +**`\stores\{sites}-store.js`** + +```js +import { defineStore } from "pinia"; + +// Custom +const secureStorage = { + setItem(key, state) { + localStorage.setItem(key, state) + }, + getItem(key) { + localStorage.getItem(key, state) + }, +} + +export const useUsersStore = defineStore({ + id: "users-store", + state: () => ({ + name: { + first: "", + last: "", + }, + }), + conserve: { + enabled: true, + strategies: [ + { storage: secureStorage, states: ["name"] }, // Save custom state + ], + }, + getters: {}, + actions: {}, +}); +``` + +# License + +[MIT License](https://opensource.org/licenses/MIT) diff --git a/package.json b/package.json new file mode 100644 index 0000000..959c802 --- /dev/null +++ b/package.json @@ -0,0 +1,36 @@ +{ + "name": "@ctechhindi/pinia-storage", + "version": "1.0.0", + "description": "Store Vue 3 Store data in the browser LocalStorage", + "homepage": "https://github.com/ctechhindi/Pinia-Storage", + "bugs": "https://github.com/ctechhindi/Pinia-Storage/issues", + "email": "ctechhindi@gmail.com", + "main": "src/index.js", + "module": "src/index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/ctechhindi/Pinia-Storage.git" + }, + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview --port 4173", + "publish": "npm publish --access public" + }, + "keywords": [ + "vue3", + "pinia", + "pinia-storage", + "storage", + "vue", + "ctechhindi" + ], + "author": "Jeevan Lal", + "license": "MIT", + "devDependencies": { + "@vitejs/plugin-vue": "^3.0.3", + "vite": "^3.0.9", + "vue": "^3.2.38", + "vue-router": "^4.1.5" + } +} \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..9926003 --- /dev/null +++ b/src/index.js @@ -0,0 +1,46 @@ +/** + * Update Storage + * @param {Object} conserve + * @param {Object} store + */ +export const updateStorage = (conserve, store) => { + const storage = conserve.storage || sessionStorage + const storeKey = conserve.key || store.$id + + if (conserve.states) { + const partialState = conserve.states.reduce((finalObj, key) => { + finalObj[key] = store.$state[key]; + return finalObj; + }, {}) + + storage.setItem(storeKey, JSON.stringify(partialState)) + } else { + storage.setItem(storeKey, JSON.stringify(store.$state)) + } +} + +// Default +function piniaStorage({ options, store }) { + if (options.conserve && options.conserve.enabled && options.conserve.strategies && options.conserve.strategies.length > 0) { + + // Get Storage and Set in the Store + options.conserve.strategies.forEach((s) => { + const storage = s.storage || sessionStorage + const storeKey = s.key || store.$id + const storageResult = storage.getItem(storeKey) + + if (storageResult) { + store.$patch(JSON.parse(storageResult)) + updateStorage(s, store) + } + }); + + store.$subscribe((mutations, state) => { + options.conserve.strategies.forEach((s) => { + updateStorage(s, store) + }) + }, { detached: true }); + } +} + +export default piniaStorage; \ No newline at end of file diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..0fa7cb6 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,13 @@ +import { fileURLToPath, URL } from 'url' +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [vue()], + resolve: { + alias: { + '@': fileURLToPath(new URL('./test', import.meta.url)) + } + } +})