@idealyst/storage 1.0.54 → 1.0.56

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.
Files changed (2) hide show
  1. package/README.md +360 -0
  2. package/package.json +4 -3
package/README.md ADDED
@@ -0,0 +1,360 @@
1
+ # @idealyst/storage
2
+
3
+ A universal, cross-platform storage solution for React and React Native applications. Provides a consistent API for persistent data storage with fallbacks from secure storage to async storage to local storage.
4
+
5
+ [![npm version](https://badge.fury.io/js/@idealyst%2Fstorage.svg)](https://badge.fury.io/js/@idealyst%2Fstorage)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Features
9
+
10
+ - 🌐 **Cross-Platform**: Works seamlessly on React Native and Web
11
+ - 🔒 **Security First**: Automatic fallback from secure storage to less secure options
12
+ - 🚀 **Simple API**: Async/await based with consistent interface
13
+ - 📱 **React Native**: Uses MMKV for high-performance storage
14
+ - 🌍 **Web**: Uses localStorage with proper error handling
15
+ - 🔧 **TypeScript**: Full type safety and IntelliSense support
16
+ - 💾 **Automatic Fallbacks**: Graceful degradation when storage methods fail
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ # Using yarn (recommended)
22
+ yarn add @idealyst/storage
23
+
24
+ # Using npm
25
+ npm install @idealyst/storage
26
+ ```
27
+
28
+ ### Platform Dependencies
29
+
30
+ **React Native:**
31
+ ```bash
32
+ # High-performance storage (recommended)
33
+ yarn add react-native-mmkv
34
+
35
+ # Follow installation instructions for react-native-mmkv
36
+ cd ios && pod install
37
+ ```
38
+
39
+ **Web:**
40
+ No additional dependencies required - uses native localStorage.
41
+
42
+ ## Quick Start
43
+
44
+ ```tsx
45
+ import { storage } from '@idealyst/storage';
46
+
47
+ // Store data
48
+ await storage.setItem('user', { name: 'John', id: 123 });
49
+ await storage.setItem('token', 'abc123');
50
+ await storage.setItem('settings', { theme: 'dark', notifications: true });
51
+
52
+ // Retrieve data
53
+ const user = await storage.getItem('user');
54
+ const token = await storage.getItem('token');
55
+ const settings = await storage.getItem('settings');
56
+
57
+ // Remove data
58
+ await storage.removeItem('token');
59
+
60
+ // Clear all data
61
+ await storage.clear();
62
+ ```
63
+
64
+ ## API Reference
65
+
66
+ ### `setItem(key: string, value: any): Promise<void>`
67
+
68
+ Stores a value with the given key. Values are automatically serialized.
69
+
70
+ ```tsx
71
+ await storage.setItem('user', { name: 'John', age: 30 });
72
+ await storage.setItem('count', 42);
73
+ await storage.setItem('isEnabled', true);
74
+ await storage.setItem('tags', ['react', 'native']);
75
+ ```
76
+
77
+ ### `getItem<T>(key: string): Promise<T | null>`
78
+
79
+ Retrieves a value by key. Returns `null` if the key doesn't exist.
80
+
81
+ ```tsx
82
+ const user = await storage.getItem<User>('user');
83
+ const count = await storage.getItem<number>('count');
84
+ const isEnabled = await storage.getItem<boolean>('isEnabled');
85
+ const tags = await storage.getItem<string[]>('tags');
86
+
87
+ if (user) {
88
+ console.log(user.name); // TypeScript knows this is a User object
89
+ }
90
+ ```
91
+
92
+ ### `removeItem(key: string): Promise<void>`
93
+
94
+ Removes a specific item from storage.
95
+
96
+ ```tsx
97
+ await storage.removeItem('user');
98
+ await storage.removeItem('temporaryData');
99
+ ```
100
+
101
+ ### `clear(): Promise<void>`
102
+
103
+ Removes all items from storage.
104
+
105
+ ```tsx
106
+ await storage.clear();
107
+ ```
108
+
109
+ ### `getAllKeys(): Promise<string[]>`
110
+
111
+ Returns all keys currently in storage.
112
+
113
+ ```tsx
114
+ const keys = await storage.getAllKeys();
115
+ console.log('Stored keys:', keys); // ['user', 'settings', 'token']
116
+ ```
117
+
118
+ ## Usage Examples
119
+
120
+ ### User Session Management
121
+
122
+ ```tsx
123
+ import { storage } from '@idealyst/storage';
124
+
125
+ interface User {
126
+ id: number;
127
+ name: string;
128
+ email: string;
129
+ }
130
+
131
+ class AuthService {
132
+ static async saveUserSession(user: User, token: string) {
133
+ await Promise.all([
134
+ storage.setItem('currentUser', user),
135
+ storage.setItem('authToken', token),
136
+ storage.setItem('loginTime', new Date().toISOString()),
137
+ ]);
138
+ }
139
+
140
+ static async getUserSession() {
141
+ const user = await storage.getItem<User>('currentUser');
142
+ const token = await storage.getItem<string>('authToken');
143
+
144
+ return user && token ? { user, token } : null;
145
+ }
146
+
147
+ static async clearSession() {
148
+ await Promise.all([
149
+ storage.removeItem('currentUser'),
150
+ storage.removeItem('authToken'),
151
+ storage.removeItem('loginTime'),
152
+ ]);
153
+ }
154
+ }
155
+ ```
156
+
157
+ ### Settings Management
158
+
159
+ ```tsx
160
+ import { storage } from '@idealyst/storage';
161
+
162
+ interface AppSettings {
163
+ theme: 'light' | 'dark';
164
+ notifications: boolean;
165
+ language: string;
166
+ fontSize: number;
167
+ }
168
+
169
+ const defaultSettings: AppSettings = {
170
+ theme: 'light',
171
+ notifications: true,
172
+ language: 'en',
173
+ fontSize: 16,
174
+ };
175
+
176
+ class SettingsService {
177
+ static async getSettings(): Promise<AppSettings> {
178
+ const stored = await storage.getItem<AppSettings>('appSettings');
179
+ return stored ? { ...defaultSettings, ...stored } : defaultSettings;
180
+ }
181
+
182
+ static async updateSettings(newSettings: Partial<AppSettings>) {
183
+ const current = await this.getSettings();
184
+ const updated = { ...current, ...newSettings };
185
+ await storage.setItem('appSettings', updated);
186
+ return updated;
187
+ }
188
+
189
+ static async resetSettings() {
190
+ await storage.setItem('appSettings', defaultSettings);
191
+ return defaultSettings;
192
+ }
193
+ }
194
+ ```
195
+
196
+ ### Cache Management
197
+
198
+ ```tsx
199
+ import { storage } from '@idealyst/storage';
200
+
201
+ interface CacheItem<T> {
202
+ data: T;
203
+ timestamp: number;
204
+ expiresIn: number; // milliseconds
205
+ }
206
+
207
+ class CacheService {
208
+ static async setCache<T>(key: string, data: T, expiresIn: number = 3600000) {
209
+ const cacheItem: CacheItem<T> = {
210
+ data,
211
+ timestamp: Date.now(),
212
+ expiresIn,
213
+ };
214
+
215
+ await storage.setItem(`cache_${key}`, cacheItem);
216
+ }
217
+
218
+ static async getCache<T>(key: string): Promise<T | null> {
219
+ const cacheItem = await storage.getItem<CacheItem<T>>(`cache_${key}`);
220
+
221
+ if (!cacheItem) return null;
222
+
223
+ const isExpired = Date.now() - cacheItem.timestamp > cacheItem.expiresIn;
224
+
225
+ if (isExpired) {
226
+ await storage.removeItem(`cache_${key}`);
227
+ return null;
228
+ }
229
+
230
+ return cacheItem.data;
231
+ }
232
+
233
+ static async clearExpiredCache() {
234
+ const keys = await storage.getAllKeys();
235
+ const cacheKeys = keys.filter(key => key.startsWith('cache_'));
236
+
237
+ for (const key of cacheKeys) {
238
+ const cacheItem = await storage.getItem<CacheItem<any>>(key);
239
+ if (cacheItem) {
240
+ const isExpired = Date.now() - cacheItem.timestamp > cacheItem.expiresIn;
241
+ if (isExpired) {
242
+ await storage.removeItem(key);
243
+ }
244
+ }
245
+ }
246
+ }
247
+ }
248
+ ```
249
+
250
+ ## Platform Implementation Details
251
+
252
+ ### React Native
253
+ - **Primary**: Uses `react-native-mmkv` for high-performance storage
254
+ - **Fallback**: Falls back to `AsyncStorage` if MMKV is unavailable
255
+ - **Security**: Data is stored securely on device
256
+ - **Performance**: MMKV provides near-instant read/write operations
257
+
258
+ ### Web
259
+ - **Primary**: Uses browser `localStorage`
260
+ - **Fallback**: Graceful handling when localStorage is unavailable (private browsing)
261
+ - **Security**: Data persists across browser sessions
262
+ - **Limitations**: ~5-10MB storage limit per domain
263
+
264
+ ## Error Handling
265
+
266
+ The storage system handles errors gracefully:
267
+
268
+ ```tsx
269
+ try {
270
+ await storage.setItem('data', largeObject);
271
+ } catch (error) {
272
+ console.error('Storage failed:', error);
273
+ // Handle storage quota exceeded or other errors
274
+ }
275
+
276
+ // Or with error checking
277
+ const result = await storage.getItem('data');
278
+ if (result === null) {
279
+ // Key doesn't exist or retrieval failed
280
+ console.log('No data found or error occurred');
281
+ }
282
+ ```
283
+
284
+ ## TypeScript Support
285
+
286
+ Full type safety with generics:
287
+
288
+ ```tsx
289
+ // Define your data types
290
+ interface UserPreferences {
291
+ theme: 'light' | 'dark';
292
+ language: string;
293
+ }
294
+
295
+ // Type-safe storage operations
296
+ await storage.setItem('preferences', { theme: 'dark', language: 'en' });
297
+ const prefs = await storage.getItem<UserPreferences>('preferences');
298
+
299
+ if (prefs) {
300
+ // TypeScript knows the exact type
301
+ console.log(prefs.theme); // ✅ Type: 'light' | 'dark'
302
+ console.log(prefs.language); // ✅ Type: string
303
+ }
304
+ ```
305
+
306
+ ## Best Practices
307
+
308
+ 1. **Use TypeScript**: Always specify types for better development experience
309
+ 2. **Handle Nulls**: Always check for null returns from `getItem`
310
+ 3. **Batch Operations**: Use `Promise.all` for multiple storage operations
311
+ 4. **Error Handling**: Wrap storage operations in try-catch blocks for critical data
312
+ 5. **Key Naming**: Use consistent, descriptive key names
313
+ 6. **Data Size**: Keep stored objects reasonably sized
314
+ 7. **Cleanup**: Periodically clean up unused data
315
+
316
+ ## Performance Considerations
317
+
318
+ - **React Native**: MMKV provides excellent performance for frequent read/write operations
319
+ - **Web**: localStorage is synchronous but wrapped in async API for consistency
320
+ - **Large Data**: Consider chunking very large objects across multiple keys
321
+ - **Frequent Updates**: Storage operations are optimized but avoid excessive writes
322
+
323
+ ## Migration Guide
324
+
325
+ If migrating from AsyncStorage or localStorage:
326
+
327
+ ```tsx
328
+ // Old AsyncStorage code
329
+ import AsyncStorage from '@react-native-async-storage/async-storage';
330
+ const value = await AsyncStorage.getItem('key');
331
+
332
+ // New @idealyst/storage code
333
+ import { storage } from '@idealyst/storage';
334
+ const value = await storage.getItem('key');
335
+ ```
336
+
337
+ The API is nearly identical with these improvements:
338
+ - Automatic JSON serialization/deserialization
339
+ - Better TypeScript support
340
+ - Cross-platform compatibility
341
+ - Performance optimizations
342
+
343
+ ## Contributing
344
+
345
+ We welcome contributions! Please see our [Contributing Guide](../../CONTRIBUTING.md) for details.
346
+
347
+ ## License
348
+
349
+ MIT © [Idealyst](https://github.com/IdealystIO)
350
+
351
+ ## Links
352
+
353
+ - [Documentation](https://github.com/IdealystIO/idealyst-framework/tree/main/packages/storage)
354
+ - [GitHub](https://github.com/IdealystIO/idealyst-framework)
355
+ - [Issues](https://github.com/IdealystIO/idealyst-framework/issues)
356
+ - [react-native-mmkv](https://github.com/mrousavy/react-native-mmkv)
357
+
358
+ ---
359
+
360
+ Built with ❤️ by the Idealyst team
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@idealyst/storage",
3
- "version": "1.0.54",
3
+ "version": "1.0.56",
4
4
  "description": "Cross-platform storage abstraction for React and React Native",
5
- "documentation": "https://github.com/your-username/idealyst-framework/tree/main/packages/storage#readme",
5
+ "documentation": "https://github.com/IdealystIO/idealyst-framework/tree/main/packages/storage#readme",
6
+ "readme": "README.md",
6
7
  "main": "src/index.ts",
7
8
  "module": "src/index.ts",
8
9
  "types": "src/index.ts",
9
10
  "react-native": "src/index.native.ts",
10
11
  "repository": {
11
12
  "type": "git",
12
- "url": "https://github.com/your-username/idealyst-framework.git",
13
+ "url": "https://github.com/IdealystIO/idealyst-framework.git",
13
14
  "directory": "packages/storage"
14
15
  },
15
16
  "author": "Your Name <your.email@example.com>",