@alwatr/local-storage 5.5.9 → 6.0.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 +46 -0
- package/README.md +226 -29
- package/dist/local-storage.provider.d.ts +74 -0
- package/dist/local-storage.provider.d.ts.map +1 -0
- package/dist/main.cjs +89 -86
- package/dist/main.cjs.map +3 -3
- package/dist/main.d.ts +25 -66
- package/dist/main.d.ts.map +1 -1
- package/dist/main.mjs +86 -86
- package/dist/main.mjs.map +3 -3
- package/dist/type.d.ts +18 -0
- package/dist/type.d.ts.map +1 -0
- package/package.json +10 -8
- package/src/main.test.js +234 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,52 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [6.0.0](https://github.com/Alwatr/nanolib/compare/@alwatr/local-storage@5.5.10...@alwatr/local-storage@6.0.0) (2025-09-13)
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
* **local-storage:** The provider's constructor config shape and public methods have changed.
|
|
11
|
+
Existing callers must be updated to the new API:
|
|
12
|
+
- Update imports/instantiation to use the new LocalStorageProvider<T>(config: LocalStorageProviderConfig<T>).
|
|
13
|
+
- Replace any old config fields / method names with the new ones (e.g. versioned key handling, defaultValue handling).
|
|
14
|
+
- Data migration behavior changed: previous-version keys are automatically removed when version > 1.
|
|
15
|
+
- Update call sites that relied on prior serialization, error handling, or return semantics.
|
|
16
|
+
|
|
17
|
+
Suggested migration steps:
|
|
18
|
+
1. Inspect the new LocalStorageProviderConfig<T> type and adapt object literal passed to the constructor.
|
|
19
|
+
2. Replace old read/write/remove calls with the new method names and signatures.
|
|
20
|
+
3. Ensure stored values match the new serialization expectations (JSON-serializable).
|
|
21
|
+
4. Run tests and rehydrate any persisted data if necessary (previous keys are removed for versions >1).
|
|
22
|
+
|
|
23
|
+
### ✨ Features
|
|
24
|
+
|
|
25
|
+
* **local-storage:** add factory function to create LocalStorageProvider with detailed documentation ([eb4a04d](https://github.com/Alwatr/nanolib/commit/eb4a04de84d69497e7489b756c172ed2b0af008d))
|
|
26
|
+
* **local-storage:** add static method to check existence of versioned items in localStorage ([8e05938](https://github.com/Alwatr/nanolib/commit/8e059382d085aa691f296b2267a372925868f974))
|
|
27
|
+
|
|
28
|
+
### 🐛 Bug Fixes
|
|
29
|
+
|
|
30
|
+
* **local-storage:** correct typo in writeDefault method name ([c0b05c0](https://github.com/Alwatr/nanolib/commit/c0b05c0417ec75e7d9bc57c224380f34472ec467))
|
|
31
|
+
* **local-storage:** simplify read method by removing type check for parsed value ([23826ef](https://github.com/Alwatr/nanolib/commit/23826ef70eb22e6f092ba2c6ce11c28b3628f2f2))
|
|
32
|
+
* **local-storage:** standardize key naming convention in LocalStorageProvider ([043cf27](https://github.com/Alwatr/nanolib/commit/043cf27881b840d5adeb79ea4a840a15ea23e262))
|
|
33
|
+
|
|
34
|
+
### 🔨 Code Refactoring
|
|
35
|
+
|
|
36
|
+
* **local-storage:** complete API rewrite for LocalStorageProvider ([29d01d8](https://github.com/Alwatr/nanolib/commit/29d01d84fbb3ed405ce46d1870d1a929de1c838c))
|
|
37
|
+
* **local-storage:** enhance logging in read and write methods for better error tracking ([2cbf404](https://github.com/Alwatr/nanolib/commit/2cbf4042fcef74de016fd1ae80f8263f9de5c610))
|
|
38
|
+
* **local-storage:** rename private key variable and update its initialization method ([e25a8ea](https://github.com/Alwatr/nanolib/commit/e25a8ea4a4b75aeac0702fc0a9ef39a5f441e54c))
|
|
39
|
+
* **local-storage:** update key generation method to static and enhance documentation ([e36fd53](https://github.com/Alwatr/nanolib/commit/e36fd5355ad4b7fa7b4e629568b9a878ae868c3e))
|
|
40
|
+
* **types:** reorganize StorageMeta and LocalStorageProviderConfig interfaces ([d3d001e](https://github.com/Alwatr/nanolib/commit/d3d001ef041ea59981551204d84bee7635cfc192))
|
|
41
|
+
|
|
42
|
+
### 🧹 Miscellaneous Chores
|
|
43
|
+
|
|
44
|
+
* add @jest/globals dependency for testing ([a024449](https://github.com/Alwatr/nanolib/commit/a024449366e6b4aa246603528dde6586dda3379e))
|
|
45
|
+
|
|
46
|
+
## [5.5.10](https://github.com/Alwatr/nanolib/compare/@alwatr/local-storage@5.5.9...@alwatr/local-storage@5.5.10) (2025-09-09)
|
|
47
|
+
|
|
48
|
+
### 🧹 Miscellaneous Chores
|
|
49
|
+
|
|
50
|
+
* remove trailing newlines from contributing sections in README files ([e8ab1bc](https://github.com/Alwatr/nanolib/commit/e8ab1bc43e0addea5ccd4c897c2cec597cb9e15f))
|
|
51
|
+
|
|
6
52
|
## [5.5.9](https://github.com/Alwatr/nanolib/compare/@alwatr/local-storage@5.5.8...@alwatr/local-storage@5.5.9) (2025-09-06)
|
|
7
53
|
|
|
8
54
|
### 🐛 Bug Fixes
|
package/README.md
CHANGED
|
@@ -1,71 +1,268 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Alwatr Local Storage Provider
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A modern, simple, and robust solution for managing versioned JSON objects in the browser's `localStorage`. This package provides a clean, class-based API with a factory function to ensure your application's data persistence is safe, maintainable, and future-proof.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
It's designed to handle data structure migrations automatically, preventing issues when your application updates and the shape of your stored data changes.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[](https://www.google.com/search?q=https://www.npmjs.com/package/%40alwatr/local-storage)
|
|
8
|
+
[](https://www.google.com/search?q=https://www.npmjs.com/package/%40alwatr/nanolib)
|
|
9
|
+
[](https://www.google.com/search?q=alwatr+local+storage)
|
|
10
|
+
[](https://www.google.com/search?q=alwatr+nanolib)
|
|
11
|
+
[](https://www.google.com/search?q=alwatr)
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
## Core Concepts
|
|
14
|
+
|
|
15
|
+
This library is built upon a few simple but powerful concepts:
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
1. **Provider Pattern**: Instead of using static functions, you create an _instance_ of a `LocalStorageProvider` for each unique data item you want to manage. This instance is configured once with a name, version, and default value, and then used to interact with that specific item.
|
|
18
|
+
|
|
19
|
+
2. **Versioning & Automatic Migration**: When you initialize a provider with a new `version` number, it automatically removes all older versions of that data from `localStorage`. This prevents conflicts and ensures the application is working with the correct data structure.
|
|
20
|
+
|
|
21
|
+
3. **Facade Factory Function**: The `createLocalStorageProvider` function acts as a clean entry point (Facade) to the library. This simplifies the API and decouples your code from the internal class implementation, making future library upgrades safer and easier.
|
|
22
|
+
|
|
23
|
+
4. **Static Existence Check**: The static method `LocalStorageProvider.has()` allows you to check if data exists _before_ creating a provider instance. This is highly efficient for scenarios where you only need to know if the data is present, without needing the data itself or a default value.
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
14
26
|
|
|
15
27
|
```bash
|
|
28
|
+
# Using yarn
|
|
16
29
|
yarn add @alwatr/local-storage
|
|
30
|
+
|
|
31
|
+
# Using npm
|
|
32
|
+
npm install @alwatr/local-storage
|
|
17
33
|
```
|
|
18
34
|
|
|
19
|
-
## Usage
|
|
35
|
+
## API and Usage
|
|
36
|
+
|
|
37
|
+
### 1\. Creating a Storage Provider
|
|
20
38
|
|
|
21
|
-
|
|
39
|
+
The recommended way to get started is by using the `createLocalStorageProvider` factory function. It encapsulates the instantiation logic and provides a clean API.
|
|
22
40
|
|
|
23
41
|
```typescript
|
|
24
|
-
import {
|
|
42
|
+
import {createLocalStorageProvider} from '@alwatr/local-storage';
|
|
43
|
+
|
|
44
|
+
// Define the shape of your data
|
|
45
|
+
interface UserSettings {
|
|
46
|
+
theme: 'light' | 'dark';
|
|
47
|
+
notifications: boolean;
|
|
48
|
+
lastLogin: number | null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Create a provider for user settings
|
|
52
|
+
const userSettingsProvider = createLocalStorageProvider<UserSettings>({
|
|
53
|
+
name: 'user-settings',
|
|
54
|
+
version: 1,
|
|
55
|
+
defaultValue: {
|
|
56
|
+
theme: 'light',
|
|
57
|
+
notifications: true,
|
|
58
|
+
lastLogin: null,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
25
61
|
```
|
|
26
62
|
|
|
27
|
-
|
|
63
|
+
### 2\. Writing Data
|
|
28
64
|
|
|
29
|
-
|
|
30
|
-
|
|
65
|
+
Use the `.write()` method on the provider instance to save data. The value will be automatically serialized to a JSON string.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
userSettingsProvider.write({
|
|
69
|
+
theme: 'dark',
|
|
70
|
+
notifications: false,
|
|
71
|
+
lastLogin: Date.now(),
|
|
72
|
+
});
|
|
31
73
|
```
|
|
32
74
|
|
|
33
|
-
###
|
|
75
|
+
### 3\. Reading Data
|
|
76
|
+
|
|
77
|
+
Use the `.read()` method to retrieve the data.
|
|
34
78
|
|
|
35
|
-
|
|
79
|
+
- If a value exists in `localStorage` and is valid JSON, it will be parsed and returned.
|
|
80
|
+
- If no value exists or if the stored value is corrupted (invalid JSON), the `defaultValue` will be written to `localStorage` and then returned. This guarantees you always receive a value of the correct type.
|
|
81
|
+
|
|
82
|
+
<!-- end list -->
|
|
36
83
|
|
|
37
84
|
```typescript
|
|
38
|
-
const
|
|
39
|
-
|
|
85
|
+
const currentSettings = userSettingsProvider.read();
|
|
86
|
+
console.log(currentSettings.theme); // "dark"
|
|
40
87
|
```
|
|
41
88
|
|
|
42
|
-
###
|
|
89
|
+
### 4\. Checking for Data Existence (The Recommended Way)
|
|
90
|
+
|
|
91
|
+
This is a critical feature for many applications. Before rendering a component or creating a full provider instance, you might need to check if the user has already saved data. Use the static `LocalStorageProvider.has()` method for this.
|
|
43
92
|
|
|
44
|
-
|
|
93
|
+
This method is highly efficient as it **does not** require a `defaultValue` and does not create a class instance.
|
|
45
94
|
|
|
46
95
|
```typescript
|
|
47
|
-
|
|
48
|
-
|
|
96
|
+
import {LocalStorageProvider} from '@alwatr/local-storage';
|
|
97
|
+
|
|
98
|
+
const formMeta = {name: 'user-survey-form', version: 1};
|
|
99
|
+
|
|
100
|
+
if (LocalStorageProvider.has(formMeta)) {
|
|
101
|
+
// The user has already filled out the form.
|
|
102
|
+
// Show a "Thank you" message instead of the form.
|
|
103
|
+
showThankYouMessage();
|
|
104
|
+
} else {
|
|
105
|
+
// No data found, so render the form.
|
|
106
|
+
renderSurveyForm();
|
|
107
|
+
}
|
|
49
108
|
```
|
|
50
109
|
|
|
51
|
-
### Removing
|
|
110
|
+
### 5\. Removing Data
|
|
52
111
|
|
|
53
|
-
|
|
112
|
+
To completely remove the item from `localStorage`, use the `.remove()` method.
|
|
54
113
|
|
|
55
114
|
```typescript
|
|
56
|
-
|
|
115
|
+
userSettingsProvider.remove();
|
|
57
116
|
```
|
|
58
117
|
|
|
59
|
-
##
|
|
118
|
+
## Best Practices
|
|
119
|
+
|
|
120
|
+
- **Always use the `createLocalStorageProvider` factory function.** It provides a stable API that protects your code from internal library changes.
|
|
121
|
+
- **Prefer `LocalStorageProvider.has()` for existence checks.** It's the most performant and cleanest way to check for data without the overhead of creating an instance and providing a `defaultValue`.
|
|
122
|
+
- **Increment the `version` number** whenever you make a breaking change to your data structure. The library will handle the cleanup of old data automatically.
|
|
60
123
|
|
|
61
|
-
|
|
124
|
+
---
|
|
62
125
|
|
|
63
126
|
## Sponsors
|
|
64
127
|
|
|
65
|
-
The following companies, organizations, and individuals support
|
|
128
|
+
The following companies, organizations, and individuals support flux ongoing maintenance and development. Become a Sponsor to get your logo on our README and website.
|
|
66
129
|
|
|
67
|
-
|
|
130
|
+
## Contributing
|
|
68
131
|
|
|
69
132
|
Contributions are welcome! Please read our [contribution guidelines](https://github.com/Alwatr/.github/blob/next/CONTRIBUTING.md) before submitting a pull request.
|
|
70
133
|
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
<br>
|
|
137
|
+
<br>
|
|
138
|
+
<br>
|
|
139
|
+
|
|
140
|
+
# Alwatr Local Storage Provider (راهنمای فارسی)
|
|
141
|
+
|
|
142
|
+
یک راهکار مدرن، ساده و قدرتمند برای مدیریت آبجکتهای JSON نسخهبندی شده در `localStorage` مرورگر. این پکیج یک API تمیز و مبتنی بر کلاس به همراه یک تابع سازنده (Factory Function) ارائه میدهد تا اطمینان حاصل شود که پایداری دادههای اپلیکیشن شما امن، قابل نگهداری و آماده برای آینده است.
|
|
143
|
+
|
|
144
|
+
این کتابخانه طوری طراحی شده است که مهاجرت (migration) ساختار داده را به صورت خودکار مدیریت کند و از بروز مشکل در هنگام بهروزرسانی اپلیکیشن و تغییر شکل دادههای ذخیره شده جلوگیری نماید.
|
|
145
|
+
|
|
146
|
+
[](https://www.google.com/search?q=https://www.npmjs.com/package/%40alwatr/local-storage)
|
|
147
|
+
[](https://www.google.com/search?q=https://www.npmjs.com/package/%40alwatr/local-storage)
|
|
148
|
+
[](https://www.google.com/search?q=alwatr+local+storage)
|
|
149
|
+
[](https://www.google.com/search?q=alwatr)
|
|
150
|
+
|
|
151
|
+
## مفاهیم اصلی
|
|
152
|
+
|
|
153
|
+
این کتابخانه بر پایه چند مفهوم ساده اما قدرتمند بنا شده است:
|
|
154
|
+
|
|
155
|
+
1. **الگوی Provider (ارائهدهنده)**: به جای استفاده از توابع استاتیک، شما برای هر آیتم دادهای که میخواهید مدیریت کنید، یک _نمونه (instance)_ از `LocalStorageProvider` میسازید. این نمونه یک بار با `name`, `version` و `defaultValue` پیکربندی شده و سپس برای تعامل با آن آیتم خاص استفاده میشود.
|
|
156
|
+
|
|
157
|
+
2. **نسخهبندی و مهاجرت خودکار**: هنگامی که شما یک Provider را با شماره `version` جدیدی مقداردهی اولیه میکنید، این کتابخانه به طور خودکار تمام نسخههای قدیمیتر آن داده را از `localStorage` حذف میکند. این کار از تداخل جلوگیری کرده و تضمین میکند که اپلیکیشن همیشه با ساختار داده صحیح کار میکند.
|
|
158
|
+
|
|
159
|
+
3. **تابع سازنده Facade**: تابع `createLocalStorageProvider` به عنوان یک نقطه ورود تمیز (Facade) به کتابخانه عمل میکند. این کار API را ساده کرده و کد شما را از پیادهسازی داخلی کلاسها جدا (decouple) میسازد، که باعث میشود ارتقاء کتابخانه در آینده امنتر و آسانتر باشد.
|
|
160
|
+
|
|
161
|
+
4. **بررسی استاتیک وجود داده**: متد استاتیک `LocalStorageProvider.has()` به شما اجازه میدهد وجود داده را _قبل_ از ساختن یک نمونه از Provider بررسی کنید. این روش برای سناریوهایی که فقط نیاز دارید بدانید دادهای وجود دارد یا نه (بدون نیاز به خود داده یا مقدار پیشفرض) بسیار کارآمد است.
|
|
162
|
+
|
|
163
|
+
## نصب
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# با استفاده از yarn
|
|
167
|
+
yarn add @alwatr/local-storage
|
|
168
|
+
|
|
169
|
+
# با استفاده از npm
|
|
170
|
+
npm install @alwatr/local-storage
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## API و راهنمای استفاده
|
|
174
|
+
|
|
175
|
+
### ۱. ساختن یک Storage Provider
|
|
176
|
+
|
|
177
|
+
بهترین روش برای شروع، استفاده از تابع سازنده `createLocalStorageProvider` است. این تابع منطق ساخت نمونه را کپسوله کرده و یک API تمیز ارائه میدهد.
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import {createLocalStorageProvider} from '@alwatr/local-storage';
|
|
181
|
+
|
|
182
|
+
// ساختار داده خود را تعریف کنید
|
|
183
|
+
interface UserSettings {
|
|
184
|
+
theme: 'light' | 'dark';
|
|
185
|
+
notifications: boolean;
|
|
186
|
+
lastLogin: number | null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// یک provider برای تنظیمات کاربر بسازید
|
|
190
|
+
const userSettingsProvider = createLocalStorageProvider<UserSettings>({
|
|
191
|
+
name: 'user-settings',
|
|
192
|
+
version: 1,
|
|
193
|
+
defaultValue: {
|
|
194
|
+
theme: 'light',
|
|
195
|
+
notifications: true,
|
|
196
|
+
lastLogin: null,
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### ۲. نوشتن داده (Write)
|
|
202
|
+
|
|
203
|
+
از متد `.write()` روی نمونه Provider برای ذخیره داده استفاده کنید. مقدار داده به صورت خودکار به رشته JSON تبدیل میشود.
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
userSettingsProvider.write({
|
|
207
|
+
theme: 'dark',
|
|
208
|
+
notifications: false,
|
|
209
|
+
lastLogin: Date.now(),
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### ۳. خواندن داده (Read)
|
|
214
|
+
|
|
215
|
+
از متد `.read()` برای بازیابی داده استفاده کنید.
|
|
216
|
+
|
|
217
|
+
- اگر مقداری در `localStorage` وجود داشته باشد و JSON معتبر باشد، آن مقدار parse شده و برگردانده میشود.
|
|
218
|
+
- اگر مقداری وجود نداشته باشد یا مقدار ذخیره شده خراب باشد (JSON نامعتبر)، `defaultValue` در `localStorage` نوشته شده و سپس برگردانده میشود. این تضمین میکند که شما همیشه یک مقدار با نوع صحیح دریافت میکنید.
|
|
219
|
+
|
|
220
|
+
<!-- end list -->
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
const currentSettings = userSettingsProvider.read();
|
|
224
|
+
console.log(currentSettings.theme); // "dark"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### ۴. بررسی وجود داده (روش پیشنهادی)
|
|
228
|
+
|
|
229
|
+
این یک قابلیت حیاتی برای بسیاری از اپلیکیشنها است. قبل از رندر کردن یک کامپوننت یا ساختن یک نمونه کامل از Provider، ممکن است لازم باشد بررسی کنید که آیا کاربر قبلاً دادهای ذخیره کرده است یا خیر. برای این کار از متد استاتیک `LocalStorageProvider.has()` استفاده کنید.
|
|
230
|
+
|
|
231
|
+
این متد بسیار کارآمد است زیرا **نیازی** به `defaultValue` ندارد و یک نمونه از کلاس نمیسازد.
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
import {LocalStorageProvider} from '@alwatr/local-storage';
|
|
235
|
+
|
|
236
|
+
const formMeta = {name: 'user-survey-form', version: 1};
|
|
237
|
+
|
|
238
|
+
if (LocalStorageProvider.has(formMeta)) {
|
|
239
|
+
// داده وجود دارد. کاربر قبلاً فرم را پر کرده است.
|
|
240
|
+
// به جای فرم، یک پیام تشکر نمایش دهید.
|
|
241
|
+
showThankYouMessage();
|
|
242
|
+
} else {
|
|
243
|
+
// دادهای یافت نشد، بنابراین فرم را نمایش دهید.
|
|
244
|
+
renderSurveyForm();
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### ۵. حذف داده (Remove)
|
|
249
|
+
|
|
250
|
+
برای حذف کامل یک آیتم از `localStorage`، از متد `.remove()` استفاده کنید.
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
userSettingsProvider.remove();
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## بهترین روشها (Best Practices)
|
|
257
|
+
|
|
258
|
+
- **همیشه از تابع سازنده `createLocalStorageProvider` استفاده کنید.** این تابع یک API پایدار فراهم میکند که کد شما را در برابر تغییرات داخلی کتابخانه محافظت میکند.
|
|
259
|
+
- **برای بررسی وجود داده، `LocalStorageProvider.has()` را ترجیح دهید.** این کارآمدترین و تمیزترین روش برای بررسی وجود داده بدون سربار ساختن یک نمونه و تعریف `defaultValue` است.
|
|
260
|
+
- **هر زمان که یک تغییر ساختاری در دادههای خود ایجاد کردید که با نسخههای قبلی ناسازگار است، شماره `version` را افزایش دهید.** کتابخانه پاکسازی دادههای قدیمی را به صورت خودکار انجام خواهد داد.
|
|
261
|
+
|
|
262
|
+
## حامیان (Sponsors)
|
|
263
|
+
|
|
264
|
+
شرکتها، سازمانها و افراد زیر از نگهداری و توسعه مداوم flux حمایت میکنند. با تبدیل شدن به یک حامی، لوگوی خود را در README و وبسایت ما قرار دهید.
|
|
265
|
+
|
|
266
|
+
## مشارکت (Contributing)
|
|
71
267
|
|
|
268
|
+
از مشارکتها استقبال میشود! لطفاً قبل از ارسال pull request، [راهنمای مشارکت ما](https://github.com/Alwatr/.github/blob/next/CONTRIBUTING.md) را مطالعه کنید.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { LocalStorageProviderConfig, StorageMeta } from './type.js';
|
|
2
|
+
/**
|
|
3
|
+
* A provider class for managing a specific, versioned item in localStorage.
|
|
4
|
+
* It encapsulates the logic for key generation, serialization, and migration.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const userSettings = new LocalStorageProvider({
|
|
9
|
+
* name: 'user-settings',
|
|
10
|
+
* version: 1,
|
|
11
|
+
* defaultValue: { theme: 'light', notifications: true }
|
|
12
|
+
* });
|
|
13
|
+
*
|
|
14
|
+
* // Write new settings
|
|
15
|
+
* userSettings.write({ theme: 'dark', notifications: false });
|
|
16
|
+
*
|
|
17
|
+
* // Read the current settings
|
|
18
|
+
* const currentSettings = userSettings.read();
|
|
19
|
+
* console.log(currentSettings); // { theme: 'dark', notifications: false }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class LocalStorageProvider<T extends JsonValue> {
|
|
23
|
+
protected readonly config_: LocalStorageProviderConfig<T>;
|
|
24
|
+
private readonly key__;
|
|
25
|
+
protected readonly logger_: import("@alwatr/logger").AlwatrLogger;
|
|
26
|
+
constructor(config_: LocalStorageProviderConfig<T>);
|
|
27
|
+
/**
|
|
28
|
+
* Generates the versioned storage key.
|
|
29
|
+
* @param meta - An object containing the name and version.
|
|
30
|
+
* @returns The versioned key string.
|
|
31
|
+
*/
|
|
32
|
+
static getKey(meta: StorageMeta): string;
|
|
33
|
+
/**
|
|
34
|
+
* Statically checks if a versioned item exists in localStorage.
|
|
35
|
+
* This method provides a high-performance way to check for data existence without the overhead of creating a full provider instance.
|
|
36
|
+
*
|
|
37
|
+
* @param meta - An object containing the name and version of the item to check.
|
|
38
|
+
* @returns `true` if the item exists, otherwise `false`.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const formExists = LocalStorageProvider.has({ name: 'user-form', version: 1 });
|
|
43
|
+
* if (formExists) {
|
|
44
|
+
* // Show the "Thank you" message
|
|
45
|
+
* } else {
|
|
46
|
+
* // Show the form
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
static has(meta: StorageMeta): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Writes the default value to localStorage and returns it.
|
|
53
|
+
*/
|
|
54
|
+
private writeDefault__;
|
|
55
|
+
/**
|
|
56
|
+
* Reads and parses the value from localStorage.
|
|
57
|
+
* If the item doesn't exist, is invalid JSON, or doesn't match the expected type,
|
|
58
|
+
* it writes and returns the default value.
|
|
59
|
+
*/
|
|
60
|
+
read(): T;
|
|
61
|
+
/**
|
|
62
|
+
* Serializes and writes a value to localStorage.
|
|
63
|
+
*/
|
|
64
|
+
write(value: T): void;
|
|
65
|
+
/**
|
|
66
|
+
* Removes the item from localStorage.
|
|
67
|
+
*/
|
|
68
|
+
remove(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Manages data migration by removing all previous versions of the item.
|
|
71
|
+
*/
|
|
72
|
+
private migrate__;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=local-storage.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-storage.provider.d.ts","sourceRoot":"","sources":["../src/local-storage.provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,0BAA0B,EAAE,WAAW,EAAC,MAAM,WAAW,CAAC;AAIvE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,oBAAoB,CAAC,CAAC,SAAS,SAAS;IAIhC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAC,CAAC;IAH5E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,SAAS,CAAC,QAAQ,CAAC,OAAO,wCAA4F;gBAEhF,OAAO,EAAE,0BAA0B,CAAC,CAAC,CAAC;IAM5E;;;;OAIG;WACW,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM;IAI/C;;;;;;;;;;;;;;;;OAgBG;WACW,GAAG,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO;IAK7C;;OAEG;IACH,OAAO,CAAC,cAAc;IAMtB;;;;OAIG;IACI,IAAI,IAAI,CAAC;IAmBhB;;OAEG;IACI,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAU5B;;OAEG;IACI,MAAM,IAAI,IAAI;IAIrB;;OAEG;IACH,OAAO,CAAC,SAAS;CASlB"}
|
package/dist/main.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* @alwatr/local-storage
|
|
1
|
+
/* @alwatr/local-storage v6.0.0 */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -21,113 +21,116 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/main.ts
|
|
22
22
|
var main_exports = {};
|
|
23
23
|
__export(main_exports, {
|
|
24
|
-
|
|
24
|
+
LocalStorageProvider: () => LocalStorageProvider,
|
|
25
|
+
createLocalStorageProvider: () => createLocalStorageProvider
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(main_exports);
|
|
28
|
+
|
|
29
|
+
// src/local-storage.provider.ts
|
|
30
|
+
var import_logger = require("@alwatr/logger");
|
|
27
31
|
var import_package_tracer = require("@alwatr/package-tracer");
|
|
28
|
-
__dev_mode__: import_package_tracer.packageTracer.add("@alwatr/local-storage", "
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
__dev_mode__: import_package_tracer.packageTracer.add("@alwatr/local-storage", "6.0.0");
|
|
33
|
+
var LocalStorageProvider = class _LocalStorageProvider {
|
|
34
|
+
constructor(config_) {
|
|
35
|
+
this.config_ = config_;
|
|
36
|
+
this.logger_ = (0, import_logger.createLogger)(`local-storage-provider: ${this.config_.name}, v: ${this.config_.version}`);
|
|
37
|
+
this.logger_.logMethodArgs?.("constructor", { config: this.config_ });
|
|
38
|
+
this.key__ = _LocalStorageProvider.getKey(this.config_);
|
|
39
|
+
this.migrate__();
|
|
35
40
|
}
|
|
36
|
-
}
|
|
37
|
-
var localJsonStorage = {
|
|
38
41
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* @
|
|
42
|
-
* @param version - Version of the item (default: 1).
|
|
43
|
-
* @returns The generated local storage key.
|
|
44
|
-
* @example
|
|
45
|
-
* ```typescript
|
|
46
|
-
* localJsonStorage.key_('myItem', 1); // myItem.v1
|
|
47
|
-
* ```
|
|
42
|
+
* Generates the versioned storage key.
|
|
43
|
+
* @param meta - An object containing the name and version.
|
|
44
|
+
* @returns The versioned key string.
|
|
48
45
|
*/
|
|
49
|
-
|
|
50
|
-
return `${name}.v${version}`;
|
|
51
|
-
}
|
|
46
|
+
static getKey(meta) {
|
|
47
|
+
return `${meta.name}.v${meta.version}`;
|
|
48
|
+
}
|
|
52
49
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
50
|
+
* Statically checks if a versioned item exists in localStorage.
|
|
51
|
+
* This method provides a high-performance way to check for data existence without the overhead of creating a full provider instance.
|
|
52
|
+
*
|
|
53
|
+
* @param meta - An object containing the name and version of the item to check.
|
|
54
|
+
* @returns `true` if the item exists, otherwise `false`.
|
|
57
55
|
*
|
|
58
|
-
* @param name - The name of the item.
|
|
59
|
-
* @param defaultValue - The default value of the item.
|
|
60
|
-
* @param version - The data structure version of the item (default: 1).
|
|
61
|
-
* @returns The parsed JSON value or the default value if the item is not found.
|
|
62
56
|
* @example
|
|
63
57
|
* ```typescript
|
|
64
|
-
* const
|
|
58
|
+
* const formExists = LocalStorageProvider.has({ name: 'user-form', version: 1 });
|
|
59
|
+
* if (formExists) {
|
|
60
|
+
* // Show the "Thank you" message
|
|
61
|
+
* } else {
|
|
62
|
+
* // Show the form
|
|
63
|
+
* }
|
|
65
64
|
* ```
|
|
66
65
|
*/
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
66
|
+
static has(meta) {
|
|
67
|
+
const key = _LocalStorageProvider.getKey(meta);
|
|
68
|
+
return localStorage.getItem(key) !== null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Writes the default value to localStorage and returns it.
|
|
72
|
+
*/
|
|
73
|
+
writeDefault__() {
|
|
74
|
+
this.logger_.logMethodArgs?.("writeDefaultــ", this.config_.defaultValue);
|
|
75
|
+
this.write(this.config_.defaultValue);
|
|
76
|
+
return this.config_.defaultValue;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Reads and parses the value from localStorage.
|
|
80
|
+
* If the item doesn't exist, is invalid JSON, or doesn't match the expected type,
|
|
81
|
+
* it writes and returns the default value.
|
|
82
|
+
*/
|
|
83
|
+
read() {
|
|
84
|
+
try {
|
|
85
|
+
const value = localStorage.getItem(this.key__);
|
|
86
|
+
if (value === null) {
|
|
87
|
+
this.logger_.logMethod?.("read//no_value");
|
|
88
|
+
return this.writeDefault__();
|
|
89
|
+
}
|
|
90
|
+
const parsedValue = JSON.parse(value);
|
|
91
|
+
this.logger_.logMethodFull?.("read//value", void 0, { parsedValue });
|
|
92
|
+
return parsedValue;
|
|
93
|
+
} catch (err) {
|
|
94
|
+
this.logger_.error("read", "read_parse_error", { err });
|
|
95
|
+
return this.writeDefault__();
|
|
79
96
|
}
|
|
80
|
-
|
|
81
|
-
if (json === null) return defaultValue;
|
|
82
|
-
return json;
|
|
83
|
-
},
|
|
97
|
+
}
|
|
84
98
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* @param name - The name of the item.
|
|
88
|
-
* @param version - The version of the item (default: 1).
|
|
89
|
-
* @returns True if the item exists, false otherwise.
|
|
90
|
-
* @example
|
|
91
|
-
* ```typescript
|
|
92
|
-
* const exists = localJsonStorage.hasItem('myItem');
|
|
93
|
-
* ```
|
|
99
|
+
* Serializes and writes a value to localStorage.
|
|
94
100
|
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
write(value) {
|
|
102
|
+
this.logger_.logMethodArgs?.("write", { value });
|
|
103
|
+
try {
|
|
104
|
+
localStorage.setItem(this.key__, JSON.stringify(value));
|
|
105
|
+
} catch (err) {
|
|
106
|
+
this.logger_.error("write", "write_stringify_error", { err });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
99
109
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* @param name - Name of the item.
|
|
103
|
-
* @param value - Value of the item.
|
|
104
|
-
* @param version - Version of the item.
|
|
105
|
-
* @example
|
|
106
|
-
* ```typescript
|
|
107
|
-
* localJsonStorage.setItem('myItem', {a: 1, b: 2});
|
|
108
|
-
* ```
|
|
110
|
+
* Removes the item from localStorage.
|
|
109
111
|
*/
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
},
|
|
112
|
+
remove() {
|
|
113
|
+
localStorage.removeItem(this.key__);
|
|
114
|
+
}
|
|
114
115
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* @param name - The name of the item to remove.
|
|
118
|
-
* @param version - The version of the item to remove. Default is 1.
|
|
119
|
-
* @example
|
|
120
|
-
* ```typescript
|
|
121
|
-
* localJsonStorage.removeItem('myItem');
|
|
122
|
-
* ```
|
|
116
|
+
* Manages data migration by removing all previous versions of the item.
|
|
123
117
|
*/
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
migrate__() {
|
|
119
|
+
if (this.config_.version <= 1) return;
|
|
120
|
+
for (let i = 1; i < this.config_.version; i++) {
|
|
121
|
+
const oldKey = _LocalStorageProvider.getKey({ name: this.config_.name, version: i });
|
|
122
|
+
localStorage.removeItem(oldKey);
|
|
123
|
+
}
|
|
127
124
|
}
|
|
128
125
|
};
|
|
126
|
+
|
|
127
|
+
// src/main.ts
|
|
128
|
+
function createLocalStorageProvider(config) {
|
|
129
|
+
return new LocalStorageProvider(config);
|
|
130
|
+
}
|
|
129
131
|
// Annotate the CommonJS export names for ESM import in node:
|
|
130
132
|
0 && (module.exports = {
|
|
131
|
-
|
|
133
|
+
LocalStorageProvider,
|
|
134
|
+
createLocalStorageProvider
|
|
132
135
|
});
|
|
133
136
|
//# sourceMappingURL=main.cjs.map
|