pinia-plugin-persist-state 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
@@ -0,0 +1,142 @@
1
+ # Contributing to pinia-plugin-persist-state
2
+
3
+ Thank you for your interest in contributing! This document provides guidelines and instructions for contributing to this project.
4
+
5
+ ## Code of Conduct
6
+
7
+ Please be respectful and constructive in all interactions with other contributors and maintainers.
8
+
9
+ ## Getting Started
10
+
11
+ 1. **Fork the repository** on GitHub
12
+ 2. **Clone your fork** locally:
13
+ ```bash
14
+ git clone https://github.com/YOUR_USERNAME/pinia-plugin-persist-state.git
15
+ cd pinia-plugin-persist-state
16
+ ```
17
+ 3. **Install dependencies**:
18
+ ```bash
19
+ npm install
20
+ ```
21
+ 4. **Create a feature branch**:
22
+ ```bash
23
+ git checkout -b feature/your-feature-name
24
+ ```
25
+
26
+ ## Development Workflow
27
+
28
+ ### Running Tests
29
+
30
+ ```bash
31
+ npm run test # Run tests in watch mode
32
+ npm run test -- run # Run tests once
33
+ npm run coverage # Generate coverage report
34
+ ```
35
+
36
+ ### Building
37
+
38
+ ```bash
39
+ npm run build # Run tests, build, and generate types
40
+ ```
41
+
42
+ ### Preview Changes
43
+
44
+ ```bash
45
+ npm run dev # Start development server
46
+ npm run preview # Preview production build
47
+ ```
48
+
49
+ ## Making Changes
50
+
51
+ ### Code Style
52
+
53
+ - Follow the existing code style in the project
54
+ - Use TypeScript for all new code
55
+ - Ensure strict TypeScript compiler options are satisfied
56
+ - Write descriptive variable and function names
57
+
58
+ ### Testing
59
+
60
+ - Write tests for all new features and bug fixes
61
+ - Ensure all existing tests pass before submitting
62
+ - Aim for >80% code coverage
63
+
64
+ ### Commits
65
+
66
+ - Write clear, descriptive commit messages
67
+ - Use conventional commits format when possible:
68
+ - `feat:` for new features
69
+ - `fix:` for bug fixes
70
+ - `docs:` for documentation
71
+ - `test:` for tests
72
+ - `refactor:` for code refactoring
73
+ - `chore:` for build/dependencies
74
+
75
+ Example:
76
+ ```
77
+ feat: add support for custom reset callbacks
78
+
79
+ - Implement resetStoreCallback in PluginSubscriberInterface
80
+ - Add tests for reset functionality
81
+ - Update documentation
82
+ ```
83
+
84
+ ## Submitting Changes
85
+
86
+ 1. **Push to your fork**:
87
+ ```bash
88
+ git push origin feature/your-feature-name
89
+ ```
90
+ 2. **Create a Pull Request** on GitHub with:
91
+ - Clear title describing the change
92
+ - Detailed description of what changed and why
93
+ - Reference to related issues if applicable
94
+ - Test results showing coverage
95
+ 3. **Address review feedback** respectfully and promptly
96
+
97
+ ## Pull Request Guidelines
98
+
99
+ - Keep PRs focused on a single feature or bug fix
100
+ - Include tests for your changes
101
+ - Update documentation if needed
102
+ - Ensure CI checks pass
103
+ - Request review from maintainers
104
+
105
+ ## Reporting Bugs
106
+
107
+ Found a bug? Please create an issue on GitHub with:
108
+
109
+ 1. **Title:** Clear, concise description
110
+ 2. **Environment:** Node.js version, npm version, OS
111
+ 3. **Steps to Reproduce:** Minimal reproduction steps
112
+ 4. **Expected Behavior:** What should happen
113
+ 5. **Actual Behavior:** What actually happens
114
+ 6. **Additional Context:** Screenshots, error traces, etc.
115
+
116
+ ## Proposing Features
117
+
118
+ Have an idea? Open a GitHub issue with:
119
+
120
+ 1. **Title:** Clear feature name
121
+ 2. **Description:** What problem does it solve?
122
+ 3. **Use Cases:** When would this be useful?
123
+ 4. **Proposed Solution:** How might it work?
124
+ 5. **Alternatives:** Other approaches considered
125
+
126
+ ## Release Process
127
+
128
+ Maintainers will:
129
+
130
+ 1. Update `CHANGELOG.md` with changes
131
+ 2. Bump version in `package.json` following Semantic Versioning
132
+ 3. Create a git tag
133
+ 4. Publish to npm
134
+ 5. Create a GitHub release
135
+
136
+ ## Questions?
137
+
138
+ - Check existing issues and discussions
139
+ - Open a new GitHub discussion if needed
140
+ - Contact maintainers via email
141
+
142
+ Thank you for contributing! 🙏
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Alexandre Bidaud
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Alexandre Bidaud
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,126 +1,126 @@
1
- # Persist Pinia State Plugin
2
-
3
- A small Pinia plugin that adds persistence and optional encryption to your Pinia stores. It integrates with browser storage (localStorage or sessionStorage) or IndexedDB and augments stores with convenient methods to persist, restore and control watching behavior.
4
-
5
- ---
6
-
7
- ## 🔧 Features
8
-
9
- - Persist store state to LocalStorage, SessionStorage or IndexedDB
10
- - Selective encryption for specific properties using Web Crypto (AES-GCM)
11
- - Per-store options via `storeOptions` when defining a store
12
- - Augmented store API: `persistState`, `remember`, `removePersistedState`, `watch`, `stopWatch`
13
- - Simple initialization through `createPersistStatePlugin(dbName?, cryptKey?)`
14
-
15
- ---
16
-
17
- ## ⚙️ Installation
18
-
19
- Install the package (example):
20
-
21
- ```bash
22
- npm install --save persist-pinia-state
23
- ```
24
-
25
- Then register the plugin with Pinia in your app entry (see `src/main.ts`):
26
-
27
- ```ts
28
- import { createApp } from 'vue'
29
- import { createPinia } from 'pinia'
30
- import { createPlugin } from 'pinia-plugin-subscription'
31
- import { createPersistStatePlugin } from 'persist-pinia-state'
32
-
33
- const app = createApp(App)
34
- const pinia = createPinia()
35
-
36
- // Pass `dbName` (e.g. 'localStorage', 'sessionStorage' or a DB name for IndexedDB)
37
- // and an optional `cryptKey` to enable encryption support
38
- pinia.use(createPlugin([
39
- createPersistStatePlugin('localStorage', 'my-secret-key')
40
- ], true))
41
-
42
- app.use(pinia)
43
- ```
44
-
45
- ---
46
-
47
- ## 📚 Usage
48
-
49
- When defining a store you can pass `storeOptions` (type: `PersistedStoreOptions`) as part of the `defineStore` options. Example in `src/stores/test.ts`:
50
-
51
- ```ts
52
- // -- using defineAStore
53
-
54
- export const useTestStore = defineAStore('testStore', () => {
55
- const myString = ref('Hello World')
56
- const myStringEncrypted = ref('Sensitive Data')
57
-
58
- return { myString, myStringEncrypted }
59
- }, {
60
- persistedPropertiesToEncrypt: ['myStringEncrypted'],
61
- watchMutation: true
62
- })
63
-
64
- // -- or using defineStore
65
-
66
- const storeOptions = {
67
- persistedPropertiesToEncrypt: ['myStringEncrypted'],
68
- watchMutation: true
69
- }
70
-
71
- export const useTestStore = defineStore('testStore', () => {
72
- const myString = ref('Hello World')
73
- const myStringEncrypted = ref('Sensitive Data')
74
-
75
- return { myString, myStringEncrypted }
76
- }, { storeOptions })
77
- ```
78
-
79
- If `persist` or `watchMutation` are `true` the plugin will attempt to persist the store state using the configured persister: localStorage, sessionStorage or IndexedDB.
80
-
81
- ---
82
-
83
- ## 🔣 PersistedStoreOptions
84
-
85
- Fields available when setting `storeOptions`:
86
-
87
- - `dbName?: string` — (Optional) Name of the database/storage to use to persist the store state (use only if different from the one defined in the plugin). Use `'localStorage'` or `'sessionStorage'` for window storage, or any other name to use IndexedDB.
88
- - `excludedKeys?: string[]` — List of state properties that should NOT be persisted.
89
- - `persist?: boolean` — Enable or disable persistence for the store (default: `false`).
90
- - `persistedPropertiesToEncrypt?: string[]` — List of property names to be encrypted when persisted.
91
- - `watchMutation?: boolean` — When `true`, plugin watches store mutations and automatically persists changes.
92
-
93
- ---
94
-
95
- ## 🧰 Augmented Store API
96
-
97
- When the plugin is active stores gain the following methods (see `PersistedStore` interface):
98
-
99
- - `persistState(): Promise<void>` — Immediately persist the current store state (ignores empty values and excluded keys).
100
- - `remember(): Promise<void>` — Load persisted state and apply it to the store (used on plugin init).
101
- - `removePersistedState(): void` — Delete the persisted entry for this store.
102
- - `watch(): void` — Start watching for mutations (sets `watchMutation = true`).
103
- - `stopWatch(): void` — Stop auto-persisting on mutations (sets `watchMutation = false`).
104
-
105
- Note: encrypted properties are automatically decrypted when remembered (if a crypto key was provided during plugin creation).
106
-
107
- ---
108
-
109
- ## 🔐 Encryption
110
-
111
- Optionally supply a `cryptKey` when creating the plugin, e.g. `createPersistStatePlugin(undefined, 'my-secret')`.
112
- The plugin uses the Web Crypto API (PBKDF2 + AES-GCM) to encrypt properties listed in `persistedPropertiesToEncrypt` on each store. Only the specified properties will be encrypted.
113
-
114
- ---
115
-
116
- ## 💡 Notes
117
-
118
- - The plugin augments Pinia store definitions using the `pinia-plugin-subscription` helper. It adds `storeOptions` to Pinia's `DefineStoreOptionsBase` type through declaration merging.
119
- - The $reset method is available for stores augmented by the plugin (also setup store 😁).
120
- - When using IndexedDB, the persister stores objects with a `storeName` key path.
121
-
122
- ---
123
-
124
- ## 📜 License
125
-
126
- MIT
1
+ # Persist Pinia State Plugin
2
+
3
+ A small Pinia plugin that adds persistence and optional encryption to your Pinia stores. It integrates with browser storage (localStorage or sessionStorage) or IndexedDB and augments stores with convenient methods to persist, restore and control watching behavior.
4
+
5
+ ---
6
+
7
+ ## 🔧 Features
8
+
9
+ - Persist store state to LocalStorage, SessionStorage or IndexedDB
10
+ - Selective encryption for specific properties using Web Crypto (AES-GCM)
11
+ - Per-store options via `storeOptions` when defining a store
12
+ - Augmented store API: `persistState`, `remember`, `removePersistedState`, `watch`, `stopWatch`
13
+ - Simple initialization through `createPersistStatePlugin(dbName?, cryptKey?)`
14
+
15
+ ---
16
+
17
+ ## ⚙️ Installation
18
+
19
+ Install the package (example):
20
+
21
+ ```bash
22
+ npm install --save persist-pinia-state
23
+ ```
24
+
25
+ Then register the plugin with Pinia in your app entry (see `src/main.ts`):
26
+
27
+ ```ts
28
+ import { createApp } from 'vue'
29
+ import { createPinia } from 'pinia'
30
+ import { createPlugin } from 'pinia-plugin-subscription'
31
+ import { createPersistStatePlugin } from 'persist-pinia-state'
32
+
33
+ const app = createApp(App)
34
+ const pinia = createPinia()
35
+
36
+ // Pass `dbName` (e.g. 'localStorage', 'sessionStorage' or a DB name for IndexedDB)
37
+ // and an optional `cryptKey` to enable encryption support
38
+ pinia.use(createPlugin([
39
+ createPersistStatePlugin('localStorage', 'my-secret-key')
40
+ ], true))
41
+
42
+ app.use(pinia)
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 📚 Usage
48
+
49
+ When defining a store you can pass `storeOptions` (type: `PersistedStoreOptions`) as part of the `defineStore` options. Example in `src/stores/test.ts`:
50
+
51
+ ```ts
52
+ // -- using defineAStore
53
+
54
+ export const useTestStore = defineAStore('testStore', () => {
55
+ const myString = ref('Hello World')
56
+ const myStringEncrypted = ref('Sensitive Data')
57
+
58
+ return { myString, myStringEncrypted }
59
+ }, {
60
+ persistedPropertiesToEncrypt: ['myStringEncrypted'],
61
+ watchMutation: true
62
+ })
63
+
64
+ // -- or using defineStore
65
+
66
+ const storeOptions = {
67
+ persistedPropertiesToEncrypt: ['myStringEncrypted'],
68
+ watchMutation: true
69
+ }
70
+
71
+ export const useTestStore = defineStore('testStore', () => {
72
+ const myString = ref('Hello World')
73
+ const myStringEncrypted = ref('Sensitive Data')
74
+
75
+ return { myString, myStringEncrypted }
76
+ }, { storeOptions })
77
+ ```
78
+
79
+ If `persist` or `watchMutation` are `true` the plugin will attempt to persist the store state using the configured persister: localStorage, sessionStorage or IndexedDB.
80
+
81
+ ---
82
+
83
+ ## 🔣 PersistedStoreOptions
84
+
85
+ Fields available when setting `storeOptions`:
86
+
87
+ - `dbName?: string` — (Optional) Name of the database/storage to use to persist the store state (use only if different from the one defined in the plugin). Use `'localStorage'` or `'sessionStorage'` for window storage, or any other name to use IndexedDB.
88
+ - `excludedKeys?: string[]` — List of state properties that should NOT be persisted.
89
+ - `persist?: boolean` — Enable or disable persistence for the store (default: `false`).
90
+ - `persistedPropertiesToEncrypt?: string[]` — List of property names to be encrypted when persisted.
91
+ - `watchMutation?: boolean` — When `true`, plugin watches store mutations and automatically persists changes.
92
+
93
+ ---
94
+
95
+ ## 🧰 Augmented Store API
96
+
97
+ When the plugin is active stores gain the following methods (see `PersistedStore` interface):
98
+
99
+ - `persistState(): Promise<void>` — Immediately persist the current store state (ignores empty values and excluded keys).
100
+ - `remember(): Promise<void>` — Load persisted state and apply it to the store (used on plugin init).
101
+ - `removePersistedState(): void` — Delete the persisted entry for this store.
102
+ - `watch(): void` — Start watching for mutations (sets `watchMutation = true`).
103
+ - `stopWatch(): void` — Stop auto-persisting on mutations (sets `watchMutation = false`).
104
+
105
+ Note: encrypted properties are automatically decrypted when remembered (if a crypto key was provided during plugin creation).
106
+
107
+ ---
108
+
109
+ ## 🔐 Encryption
110
+
111
+ Optionally supply a `cryptKey` when creating the plugin, e.g. `createPersistStatePlugin(undefined, 'my-secret')`.
112
+ The plugin uses the Web Crypto API (PBKDF2 + AES-GCM) to encrypt properties listed in `persistedPropertiesToEncrypt` on each store. Only the specified properties will be encrypted.
113
+
114
+ ---
115
+
116
+ ## 💡 Notes
117
+
118
+ - The plugin augments Pinia store definitions using the `pinia-plugin-subscription` helper. It adds `storeOptions` to Pinia's `DefineStoreOptionsBase` type through declaration merging.
119
+ - The $reset method is available for stores augmented by the plugin (also setup store 😁).
120
+ - When using IndexedDB, the persister stores objects with a `storeName` key path.
121
+
122
+ ---
123
+
124
+ ## 📜 License
125
+
126
+ MIT
package/SECURITY.md ADDED
@@ -0,0 +1,75 @@
1
+ # Security Policy
2
+
3
+ ## Reporting Security Vulnerabilities
4
+
5
+ If you discover a security vulnerability in pinia-plugin-subscription, please do **NOT** open a public GitHub issue. Instead, please email the maintainers privately.
6
+
7
+ **Email:** [Security Contact - reach out via GitHub profile]
8
+
9
+ Please include:
10
+
11
+ - Description of the vulnerability
12
+ - Steps to reproduce
13
+ - Potential impact
14
+ - Suggested fix (if available)
15
+
16
+ We will:
17
+
18
+ 1. Acknowledge your report within 48 hours
19
+ 2. Investigate the issue thoroughly
20
+ 3. Work on a fix
21
+ 4. Release a patched version
22
+ 5. Credit you (if desired) in the release notes
23
+
24
+ ## Supported Versions
25
+
26
+ | Version | Supported |
27
+ |---------|-----------|
28
+ | 0.1.x | ✅ Yes |
29
+ | < 0.1 | ❌ No |
30
+
31
+ ## Security Best Practices
32
+
33
+ When using pinia-plugin-subscription:
34
+
35
+ 1. **Keep Dependencies Updated:** Regularly update Pinia, Vue, and other dependencies to the latest versions
36
+ 2. **Review Plugin Code:** Always review subscriber code before using in production
37
+ 3. **Validate Store Data:** Validate data before storing in Pinia stores
38
+ 4. **Debug Mode:** Disable debug mode in production (set `false` when calling `createPlugin`)
39
+
40
+ ## Dependencies Security
41
+
42
+ This project depends on:
43
+
44
+ - **Pinia** - Vue state management
45
+ - **Vue** - JavaScript framework
46
+
47
+ We monitor these dependencies for vulnerabilities and recommend keeping them updated.
48
+
49
+ ## Vulnerability Disclosure Timeline
50
+
51
+ - **Day 0:** Report received
52
+ - **Day 1-2:** Initial assessment
53
+ - **Day 3-7:** Fix development
54
+ - **Day 7-14:** Security release
55
+ - **Day 14:** Public disclosure
56
+
57
+ ## Scope
58
+
59
+ This policy covers:
60
+
61
+ - ✅ Code in the pinia-plugin-subscription repository
62
+ - ✅ Published npm packages
63
+ - ✅ Security of the plugin API
64
+
65
+ This policy does NOT cover:
66
+
67
+ - ❌ Security of Pinia or Vue (report to their respective projects)
68
+ - ❌ Security of applications using this plugin
69
+ - ❌ Social engineering attacks
70
+
71
+ ## Questions
72
+
73
+ For general security questions or concerns, open a private security advisory on GitHub.
74
+
75
+ Thank you for helping keep pinia-plugin-subscription secure! 🔒