@umituz/react-native-storage 1.5.0 → 2.3.2
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/README.md +0 -0
- package/package.json +28 -10
- package/src/__tests__/integration.test.ts +391 -0
- package/src/__tests__/mocks/asyncStorage.mock.ts +52 -0
- package/src/__tests__/performance.test.ts +351 -0
- package/src/__tests__/setup.ts +63 -0
- package/src/application/ports/IStorageRepository.ts +0 -12
- package/src/domain/constants/CacheDefaults.ts +64 -0
- package/src/domain/entities/CachedValue.ts +86 -0
- package/src/domain/entities/StorageResult.ts +1 -3
- package/src/domain/entities/__tests__/CachedValue.test.ts +149 -0
- package/src/domain/entities/__tests__/StorageResult.test.ts +122 -0
- package/src/domain/errors/StorageError.ts +0 -2
- package/src/domain/errors/__tests__/StorageError.test.ts +127 -0
- package/src/domain/factories/StoreFactory.ts +33 -0
- package/src/domain/types/Store.ts +18 -0
- package/src/domain/utils/CacheKeyGenerator.ts +66 -0
- package/src/domain/utils/__tests__/devUtils.test.ts +97 -0
- package/src/domain/utils/devUtils.ts +37 -0
- package/src/domain/value-objects/StorageKey.ts +27 -29
- package/src/index.ts +59 -1
- package/src/infrastructure/adapters/StorageService.ts +8 -6
- package/src/infrastructure/repositories/AsyncStorageRepository.ts +27 -108
- package/src/infrastructure/repositories/BaseStorageOperations.ts +101 -0
- package/src/infrastructure/repositories/BatchStorageOperations.ts +42 -0
- package/src/infrastructure/repositories/StringStorageOperations.ts +44 -0
- package/src/infrastructure/repositories/__tests__/AsyncStorageRepository.test.ts +169 -0
- package/src/infrastructure/repositories/__tests__/BaseStorageOperations.test.ts +200 -0
- package/src/presentation/hooks/CacheStorageOperations.ts +95 -0
- package/src/presentation/hooks/__tests__/usePersistentCache.test.ts +404 -0
- package/src/presentation/hooks/__tests__/useStorage.test.ts +246 -0
- package/src/presentation/hooks/__tests__/useStorageState.test.ts +292 -0
- package/src/presentation/hooks/useCacheState.ts +55 -0
- package/src/presentation/hooks/usePersistentCache.ts +154 -0
- package/src/presentation/hooks/useStorage.ts +4 -3
- package/src/presentation/hooks/useStorageState.ts +24 -8
- package/src/presentation/hooks/useStore.ts +15 -0
- package/src/types/global.d.ts +40 -0
- package/LICENSE +0 -22
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AsyncStorageRepository Tests
|
|
3
|
+
*
|
|
4
|
+
* Unit tests for AsyncStorageRepository
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { AsyncStorageRepository } from '../AsyncStorageRepository';
|
|
8
|
+
import { AsyncStorage } from '../../__tests__/mocks/asyncStorage.mock';
|
|
9
|
+
|
|
10
|
+
describe('AsyncStorageRepository', () => {
|
|
11
|
+
let repository: AsyncStorageRepository;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
repository = new AsyncStorageRepository();
|
|
15
|
+
(AsyncStorage as any).__clear();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe('Composition', () => {
|
|
19
|
+
it('should use composition pattern', () => {
|
|
20
|
+
expect(repository).toBeInstanceOf(AsyncStorageRepository);
|
|
21
|
+
|
|
22
|
+
// Test that all methods are available
|
|
23
|
+
expect(typeof repository.getItem).toBe('function');
|
|
24
|
+
expect(typeof repository.setItem).toBe('function');
|
|
25
|
+
expect(typeof repository.getString).toBe('function');
|
|
26
|
+
expect(typeof repository.setString).toBe('function');
|
|
27
|
+
expect(typeof repository.removeItem).toBe('function');
|
|
28
|
+
expect(typeof repository.hasItem).toBe('function');
|
|
29
|
+
expect(typeof repository.clearAll).toBe('function');
|
|
30
|
+
expect(typeof repository.getMultiple).toBe('function');
|
|
31
|
+
expect(typeof repository.getAllKeys).toBe('function');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('Delegation', () => {
|
|
36
|
+
it('should delegate getItem to BaseStorageOperations', async () => {
|
|
37
|
+
const key = 'test-key';
|
|
38
|
+
const defaultValue = 'default';
|
|
39
|
+
const expectedValue = 'test-value';
|
|
40
|
+
|
|
41
|
+
await AsyncStorage.setItem(key, JSON.stringify(expectedValue));
|
|
42
|
+
|
|
43
|
+
const result = await repository.getItem(key, defaultValue);
|
|
44
|
+
|
|
45
|
+
expect(result.success).toBe(true);
|
|
46
|
+
expect(result.data).toBe(expectedValue);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should delegate setItem to BaseStorageOperations', async () => {
|
|
50
|
+
const key = 'test-key';
|
|
51
|
+
const value = 'test-value';
|
|
52
|
+
|
|
53
|
+
const result = await repository.setItem(key, value);
|
|
54
|
+
|
|
55
|
+
expect(result.success).toBe(true);
|
|
56
|
+
expect(result.data).toBe(value);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should delegate getString to StringStorageOperations', async () => {
|
|
60
|
+
const key = 'test-key';
|
|
61
|
+
const defaultValue = 'default';
|
|
62
|
+
const expectedValue = 'test-string';
|
|
63
|
+
|
|
64
|
+
await AsyncStorage.setItem(key, expectedValue);
|
|
65
|
+
|
|
66
|
+
const result = await repository.getString(key, defaultValue);
|
|
67
|
+
|
|
68
|
+
expect(result.success).toBe(true);
|
|
69
|
+
expect(result.data).toBe(expectedValue);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should delegate setString to StringStorageOperations', async () => {
|
|
73
|
+
const key = 'test-key';
|
|
74
|
+
const value = 'test-string';
|
|
75
|
+
|
|
76
|
+
const result = await repository.setString(key, value);
|
|
77
|
+
|
|
78
|
+
expect(result.success).toBe(true);
|
|
79
|
+
expect(result.data).toBe(value);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should delegate removeItem to BaseStorageOperations', async () => {
|
|
83
|
+
const key = 'test-key';
|
|
84
|
+
|
|
85
|
+
await AsyncStorage.setItem(key, 'test-value');
|
|
86
|
+
|
|
87
|
+
const result = await repository.removeItem(key);
|
|
88
|
+
|
|
89
|
+
expect(result.success).toBe(true);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should delegate hasItem to BaseStorageOperations', async () => {
|
|
93
|
+
const key = 'test-key';
|
|
94
|
+
|
|
95
|
+
await AsyncStorage.setItem(key, 'test-value');
|
|
96
|
+
|
|
97
|
+
const exists = await repository.hasItem(key);
|
|
98
|
+
|
|
99
|
+
expect(exists).toBe(true);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should delegate clearAll to BaseStorageOperations', async () => {
|
|
103
|
+
await AsyncStorage.setItem('key1', 'value1');
|
|
104
|
+
await AsyncStorage.setItem('key2', 'value2');
|
|
105
|
+
|
|
106
|
+
const result = await repository.clearAll();
|
|
107
|
+
|
|
108
|
+
expect(result.success).toBe(true);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should delegate getMultiple to BatchStorageOperations', async () => {
|
|
112
|
+
const keys = ['key1', 'key2'];
|
|
113
|
+
|
|
114
|
+
await AsyncStorage.setItem('key1', 'value1');
|
|
115
|
+
await AsyncStorage.setItem('key2', 'value2');
|
|
116
|
+
|
|
117
|
+
const result = await repository.getMultiple(keys);
|
|
118
|
+
|
|
119
|
+
expect(result.success).toBe(true);
|
|
120
|
+
expect(result.data).toEqual({
|
|
121
|
+
key1: 'value1',
|
|
122
|
+
key2: 'value2'
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should delegate getAllKeys to BatchStorageOperations', async () => {
|
|
127
|
+
await AsyncStorage.setItem('key1', 'value1');
|
|
128
|
+
await AsyncStorage.setItem('key2', 'value2');
|
|
129
|
+
|
|
130
|
+
const result = await repository.getAllKeys();
|
|
131
|
+
|
|
132
|
+
expect(result.success).toBe(true);
|
|
133
|
+
expect(result.data).toEqual(expect.arrayContaining(['key1', 'key2']));
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
describe('Error Handling', () => {
|
|
138
|
+
it('should handle errors from delegated operations', async () => {
|
|
139
|
+
const key = 'test-key';
|
|
140
|
+
|
|
141
|
+
// Mock error in AsyncStorage
|
|
142
|
+
(AsyncStorage.getItem as jest.Mock).mockRejectedValue(new Error('Storage error'));
|
|
143
|
+
|
|
144
|
+
const result = await repository.getItem(key, 'default');
|
|
145
|
+
|
|
146
|
+
expect(result.success).toBe(false);
|
|
147
|
+
expect(result.error).toBeDefined();
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
describe('Type Safety', () => {
|
|
152
|
+
it('should maintain type safety for generic methods', async () => {
|
|
153
|
+
interface TestData {
|
|
154
|
+
id: number;
|
|
155
|
+
name: string;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const key = 'typed-key';
|
|
159
|
+
const data: TestData = { id: 1, name: 'test' };
|
|
160
|
+
|
|
161
|
+
const setResult = await repository.setItem<TestData>(key, data);
|
|
162
|
+
const getResult = await repository.getItem<TestData>(key, { id: 0, name: '' });
|
|
163
|
+
|
|
164
|
+
expect(setResult.success).toBe(true);
|
|
165
|
+
expect(getResult.success).toBe(true);
|
|
166
|
+
expect(getResult.data).toEqual(data);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseStorageOperations Tests
|
|
3
|
+
*
|
|
4
|
+
* Unit tests for BaseStorageOperations
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { BaseStorageOperations } from '../BaseStorageOperations';
|
|
8
|
+
import { AsyncStorage } from '../../__tests__/mocks/asyncStorage.mock';
|
|
9
|
+
import { StorageReadError, StorageWriteError, StorageDeleteError } from '../../../domain/errors/StorageError';
|
|
10
|
+
|
|
11
|
+
describe('BaseStorageOperations', () => {
|
|
12
|
+
let baseOps: BaseStorageOperations;
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
baseOps = new BaseStorageOperations();
|
|
16
|
+
(AsyncStorage as any).__clear();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
describe('getItem', () => {
|
|
20
|
+
it('should get item successfully', async () => {
|
|
21
|
+
const key = 'test-key';
|
|
22
|
+
const value = { test: 'value' };
|
|
23
|
+
const defaultValue = { default: true };
|
|
24
|
+
|
|
25
|
+
// Setup
|
|
26
|
+
await AsyncStorage.setItem(key, JSON.stringify(value));
|
|
27
|
+
|
|
28
|
+
// Test
|
|
29
|
+
const result = await baseOps.getItem(key, defaultValue);
|
|
30
|
+
|
|
31
|
+
expect(result.success).toBe(true);
|
|
32
|
+
expect(result.data).toEqual(value);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should return default value for missing key', async () => {
|
|
36
|
+
const key = 'missing-key';
|
|
37
|
+
const defaultValue = { default: true };
|
|
38
|
+
|
|
39
|
+
const result = await baseOps.getItem(key, defaultValue);
|
|
40
|
+
|
|
41
|
+
expect(result.success).toBe(true);
|
|
42
|
+
expect(result.data).toBe(defaultValue);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should handle deserialization error', async () => {
|
|
46
|
+
const key = 'invalid-json-key';
|
|
47
|
+
const defaultValue = { default: true };
|
|
48
|
+
|
|
49
|
+
// Setup invalid JSON
|
|
50
|
+
await AsyncStorage.setItem(key, 'invalid-json');
|
|
51
|
+
|
|
52
|
+
const result = await baseOps.getItem(key, defaultValue);
|
|
53
|
+
|
|
54
|
+
expect(result.success).toBe(false);
|
|
55
|
+
expect(result.data).toBe(defaultValue);
|
|
56
|
+
expect(result.error).toBeInstanceOf(StorageReadError);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should handle storage read error', async () => {
|
|
60
|
+
const key = 'test-key';
|
|
61
|
+
const defaultValue = { default: true };
|
|
62
|
+
|
|
63
|
+
// Mock storage error
|
|
64
|
+
(AsyncStorage.getItem as jest.Mock).mockRejectedValue(new Error('Storage error'));
|
|
65
|
+
|
|
66
|
+
const result = await baseOps.getItem(key, defaultValue);
|
|
67
|
+
|
|
68
|
+
expect(result.success).toBe(false);
|
|
69
|
+
expect(result.data).toBe(defaultValue);
|
|
70
|
+
expect(result.error).toBeInstanceOf(StorageReadError);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('setItem', () => {
|
|
75
|
+
it('should set item successfully', async () => {
|
|
76
|
+
const key = 'test-key';
|
|
77
|
+
const value = { test: 'value' };
|
|
78
|
+
|
|
79
|
+
const result = await baseOps.setItem(key, value);
|
|
80
|
+
|
|
81
|
+
expect(result.success).toBe(true);
|
|
82
|
+
expect(result.data).toEqual(value);
|
|
83
|
+
|
|
84
|
+
// Verify storage
|
|
85
|
+
const stored = await AsyncStorage.getItem(key);
|
|
86
|
+
expect(JSON.parse(stored!)).toEqual(value);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should handle serialization error', async () => {
|
|
90
|
+
const key = 'test-key';
|
|
91
|
+
const value = { circular: {} };
|
|
92
|
+
value.circular = value; // Create circular reference
|
|
93
|
+
|
|
94
|
+
const result = await baseOps.setItem(key, value);
|
|
95
|
+
|
|
96
|
+
expect(result.success).toBe(false);
|
|
97
|
+
expect(result.error).toBeInstanceOf(StorageWriteError);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should handle storage write error', async () => {
|
|
101
|
+
const key = 'test-key';
|
|
102
|
+
const value = { test: 'value' };
|
|
103
|
+
|
|
104
|
+
// Mock storage error
|
|
105
|
+
(AsyncStorage.setItem as jest.Mock).mockRejectedValue(new Error('Storage error'));
|
|
106
|
+
|
|
107
|
+
const result = await baseOps.setItem(key, value);
|
|
108
|
+
|
|
109
|
+
expect(result.success).toBe(false);
|
|
110
|
+
expect(result.error).toBeInstanceOf(StorageWriteError);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe('removeItem', () => {
|
|
115
|
+
it('should remove item successfully', async () => {
|
|
116
|
+
const key = 'test-key';
|
|
117
|
+
|
|
118
|
+
// Setup
|
|
119
|
+
await AsyncStorage.setItem(key, 'test-value');
|
|
120
|
+
|
|
121
|
+
const result = await baseOps.removeItem(key);
|
|
122
|
+
|
|
123
|
+
expect(result.success).toBe(true);
|
|
124
|
+
|
|
125
|
+
// Verify removal
|
|
126
|
+
const stored = await AsyncStorage.getItem(key);
|
|
127
|
+
expect(stored).toBeNull();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('should handle storage delete error', async () => {
|
|
131
|
+
const key = 'test-key';
|
|
132
|
+
|
|
133
|
+
// Mock storage error
|
|
134
|
+
(AsyncStorage.removeItem as jest.Mock).mockRejectedValue(new Error('Storage error'));
|
|
135
|
+
|
|
136
|
+
const result = await baseOps.removeItem(key);
|
|
137
|
+
|
|
138
|
+
expect(result.success).toBe(false);
|
|
139
|
+
expect(result.error).toBeInstanceOf(StorageDeleteError);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('hasItem', () => {
|
|
144
|
+
it('should return true for existing item', async () => {
|
|
145
|
+
const key = 'test-key';
|
|
146
|
+
|
|
147
|
+
// Setup
|
|
148
|
+
await AsyncStorage.setItem(key, 'test-value');
|
|
149
|
+
|
|
150
|
+
const exists = await baseOps.hasItem(key);
|
|
151
|
+
|
|
152
|
+
expect(exists).toBe(true);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('should return false for missing item', async () => {
|
|
156
|
+
const key = 'missing-key';
|
|
157
|
+
|
|
158
|
+
const exists = await baseOps.hasItem(key);
|
|
159
|
+
|
|
160
|
+
expect(exists).toBe(false);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('should return false on storage error', async () => {
|
|
164
|
+
const key = 'test-key';
|
|
165
|
+
|
|
166
|
+
// Mock storage error
|
|
167
|
+
(AsyncStorage.getItem as jest.Mock).mockRejectedValue(new Error('Storage error'));
|
|
168
|
+
|
|
169
|
+
const exists = await baseOps.hasItem(key);
|
|
170
|
+
|
|
171
|
+
expect(exists).toBe(false);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe('clearAll', () => {
|
|
176
|
+
it('should clear all storage successfully', async () => {
|
|
177
|
+
// Setup
|
|
178
|
+
await AsyncStorage.setItem('key1', 'value1');
|
|
179
|
+
await AsyncStorage.setItem('key2', 'value2');
|
|
180
|
+
|
|
181
|
+
const result = await baseOps.clearAll();
|
|
182
|
+
|
|
183
|
+
expect(result.success).toBe(true);
|
|
184
|
+
|
|
185
|
+
// Verify clear
|
|
186
|
+
const keys = await AsyncStorage.getAllKeys();
|
|
187
|
+
expect(keys).toHaveLength(0);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should handle storage clear error', async () => {
|
|
191
|
+
// Mock storage error
|
|
192
|
+
(AsyncStorage.clear as jest.Mock).mockRejectedValue(new Error('Storage error'));
|
|
193
|
+
|
|
194
|
+
const result = await baseOps.clearAll();
|
|
195
|
+
|
|
196
|
+
expect(result.success).toBe(false);
|
|
197
|
+
expect(result.error).toBeInstanceOf(StorageDeleteError);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache Storage Operations
|
|
3
|
+
*
|
|
4
|
+
* Handles cache storage operations following Single Responsibility Principle
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { storageRepository } from '../../infrastructure/repositories/AsyncStorageRepository';
|
|
8
|
+
import type { CachedValue } from '../../domain/entities/CachedValue';
|
|
9
|
+
import { createCachedValue } from '../../domain/entities/CachedValue';
|
|
10
|
+
import { devWarn } from '../../domain/utils/devUtils';
|
|
11
|
+
|
|
12
|
+
export interface CacheStorageOptions {
|
|
13
|
+
ttl?: number;
|
|
14
|
+
version?: number;
|
|
15
|
+
enabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Handles cache storage operations with proper error handling and memory management
|
|
20
|
+
*/
|
|
21
|
+
export class CacheStorageOperations {
|
|
22
|
+
private static instance: CacheStorageOperations | null = null;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Singleton pattern to prevent memory leaks
|
|
26
|
+
*/
|
|
27
|
+
static getInstance(): CacheStorageOperations {
|
|
28
|
+
if (!CacheStorageOperations.instance) {
|
|
29
|
+
CacheStorageOperations.instance = new CacheStorageOperations();
|
|
30
|
+
}
|
|
31
|
+
return CacheStorageOperations.instance;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Reset singleton instance (useful for testing)
|
|
36
|
+
*/
|
|
37
|
+
static resetInstance(): void {
|
|
38
|
+
CacheStorageOperations.instance = null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Load cached data from storage
|
|
43
|
+
*/
|
|
44
|
+
async loadFromStorage<T>(
|
|
45
|
+
key: string,
|
|
46
|
+
version?: number
|
|
47
|
+
): Promise<CachedValue<T> | null> {
|
|
48
|
+
try {
|
|
49
|
+
const result = await storageRepository.getString(key, '');
|
|
50
|
+
|
|
51
|
+
if (result.success && result.data) {
|
|
52
|
+
const cached = JSON.parse(result.data) as CachedValue<T>;
|
|
53
|
+
return cached;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return null;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
devWarn(`CacheStorageOperations: Failed to load cache for key "${key}"`, error);
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Save data to cache storage
|
|
65
|
+
*/
|
|
66
|
+
async saveToStorage<T>(
|
|
67
|
+
key: string,
|
|
68
|
+
value: T,
|
|
69
|
+
options: CacheStorageOptions = {}
|
|
70
|
+
): Promise<void> {
|
|
71
|
+
const { ttl, version, enabled = true } = options;
|
|
72
|
+
|
|
73
|
+
if (!enabled) return;
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
const cached = createCachedValue(value, ttl || 0, version);
|
|
77
|
+
await storageRepository.setString(key, JSON.stringify(cached));
|
|
78
|
+
} catch (error) {
|
|
79
|
+
devWarn(`CacheStorageOperations: Failed to save cache for key "${key}"`, error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Clear cached data from storage
|
|
85
|
+
*/
|
|
86
|
+
async clearFromStorage(key: string, enabled = true): Promise<void> {
|
|
87
|
+
if (!enabled) return;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
await storageRepository.removeItem(key);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
devWarn(`CacheStorageOperations: Failed to clear cache for key "${key}"`, error);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|