@umituz/react-native-design-system 2.8.7 → 2.8.8

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 (128) hide show
  1. package/package.json +5 -6
  2. package/src/device/infrastructure/repositories/LegacyDeviceIdRepository.ts +1 -1
  3. package/src/device/infrastructure/services/DeviceFeatureService.ts +1 -1
  4. package/src/exception/infrastructure/services/ExceptionLogger.ts +1 -1
  5. package/src/exception/infrastructure/storage/ExceptionStore.ts +1 -1
  6. package/src/exports/filesystem.ts +1 -0
  7. package/src/exports/storage.ts +1 -0
  8. package/src/filesystem/domain/constants/FileConstants.ts +20 -0
  9. package/src/filesystem/domain/entities/File.ts +20 -0
  10. package/src/filesystem/domain/types/FileTypes.ts +43 -0
  11. package/src/filesystem/domain/utils/FileUtils.ts +86 -0
  12. package/src/filesystem/index.ts +23 -0
  13. package/src/filesystem/infrastructure/services/FileSystemService.ts +45 -0
  14. package/src/filesystem/infrastructure/services/cache.service.ts +48 -0
  15. package/src/filesystem/infrastructure/services/directory.service.ts +66 -0
  16. package/src/filesystem/infrastructure/services/download.constants.ts +6 -0
  17. package/src/filesystem/infrastructure/services/download.service.ts +74 -0
  18. package/src/filesystem/infrastructure/services/download.types.ts +7 -0
  19. package/src/filesystem/infrastructure/services/encoding.service.ts +25 -0
  20. package/src/filesystem/infrastructure/services/file-info.service.ts +52 -0
  21. package/src/filesystem/infrastructure/services/file-manager.service.ts +81 -0
  22. package/src/filesystem/infrastructure/services/file-path.service.ts +22 -0
  23. package/src/filesystem/infrastructure/services/file-reader.service.ts +52 -0
  24. package/src/filesystem/infrastructure/services/file-writer.service.ts +32 -0
  25. package/src/filesystem/infrastructure/utils/blob.utils.ts +20 -0
  26. package/src/image/infrastructure/services/ImageStorageService.ts +1 -1
  27. package/src/index.ts +9 -0
  28. package/src/molecules/alerts/AlertStore.ts +1 -1
  29. package/src/molecules/calendar/infrastructure/storage/EventActions.ts +1 -1
  30. package/src/molecules/calendar/infrastructure/stores/storageAdapter.ts +1 -1
  31. package/src/offline/infrastructure/storage/OfflineStore.ts +1 -1
  32. package/src/onboarding/infrastructure/storage/OnboardingStore.ts +2 -2
  33. package/src/onboarding/infrastructure/storage/__tests__/OnboardingStore.test.ts +1 -1
  34. package/src/onboarding/infrastructure/storage/actions/answerActions.ts +1 -1
  35. package/src/onboarding/infrastructure/storage/actions/storageHelpers.ts +1 -1
  36. package/src/storage/README.md +185 -0
  37. package/src/storage/__tests__/integration.test.ts +391 -0
  38. package/src/storage/__tests__/mocks/asyncStorage.mock.ts +52 -0
  39. package/src/storage/__tests__/performance.test.tsx +352 -0
  40. package/src/storage/__tests__/setup.ts +63 -0
  41. package/src/storage/application/README.md +158 -0
  42. package/src/storage/application/ports/IStorageRepository.ts +61 -0
  43. package/src/storage/application/ports/README.md +127 -0
  44. package/src/storage/cache/README.md +154 -0
  45. package/src/storage/cache/__tests__/PerformanceAndMemory.test.ts +387 -0
  46. package/src/storage/cache/__tests__/setup.ts +19 -0
  47. package/src/storage/cache/domain/Cache.ts +146 -0
  48. package/src/storage/cache/domain/CacheManager.md +83 -0
  49. package/src/storage/cache/domain/CacheManager.ts +48 -0
  50. package/src/storage/cache/domain/CacheStatsTracker.md +169 -0
  51. package/src/storage/cache/domain/CacheStatsTracker.ts +49 -0
  52. package/src/storage/cache/domain/CachedValue.md +97 -0
  53. package/src/storage/cache/domain/ErrorHandler.md +99 -0
  54. package/src/storage/cache/domain/ErrorHandler.ts +42 -0
  55. package/src/storage/cache/domain/PatternMatcher.md +122 -0
  56. package/src/storage/cache/domain/PatternMatcher.ts +30 -0
  57. package/src/storage/cache/domain/README.md +118 -0
  58. package/src/storage/cache/domain/__tests__/Cache.test.ts +293 -0
  59. package/src/storage/cache/domain/__tests__/CacheManager.test.ts +276 -0
  60. package/src/storage/cache/domain/__tests__/ErrorHandler.test.ts +303 -0
  61. package/src/storage/cache/domain/__tests__/PatternMatcher.test.ts +261 -0
  62. package/src/storage/cache/domain/strategies/EvictionStrategy.ts +9 -0
  63. package/src/storage/cache/domain/strategies/FIFOStrategy.ts +12 -0
  64. package/src/storage/cache/domain/strategies/LFUStrategy.ts +22 -0
  65. package/src/storage/cache/domain/strategies/LRUStrategy.ts +22 -0
  66. package/src/storage/cache/domain/strategies/README.md +117 -0
  67. package/src/storage/cache/domain/strategies/TTLStrategy.ts +23 -0
  68. package/src/storage/cache/domain/strategies/__tests__/EvictionStrategies.test.ts +293 -0
  69. package/src/storage/cache/domain/types/Cache.ts +28 -0
  70. package/src/storage/cache/domain/types/README.md +107 -0
  71. package/src/storage/cache/index.ts +28 -0
  72. package/src/storage/cache/infrastructure/README.md +126 -0
  73. package/src/storage/cache/infrastructure/TTLCache.ts +103 -0
  74. package/src/storage/cache/infrastructure/__tests__/TTLCache.test.ts +303 -0
  75. package/src/storage/cache/presentation/README.md +123 -0
  76. package/src/storage/cache/presentation/__tests__/ReactHooks.test.ts +514 -0
  77. package/src/storage/cache/presentation/useCache.ts +76 -0
  78. package/src/storage/cache/presentation/useCachedValue.ts +88 -0
  79. package/src/storage/cache/types.d.ts +3 -0
  80. package/src/storage/domain/README.md +128 -0
  81. package/src/storage/domain/constants/CacheDefaults.ts +64 -0
  82. package/src/storage/domain/constants/README.md +105 -0
  83. package/src/storage/domain/entities/CachedValue.ts +86 -0
  84. package/src/storage/domain/entities/README.md +109 -0
  85. package/src/storage/domain/entities/StorageResult.ts +75 -0
  86. package/src/storage/domain/entities/__tests__/CachedValue.test.ts +149 -0
  87. package/src/storage/domain/entities/__tests__/StorageResult.test.ts +122 -0
  88. package/src/storage/domain/errors/README.md +126 -0
  89. package/src/storage/domain/errors/StorageError.ts +81 -0
  90. package/src/storage/domain/errors/__tests__/StorageError.test.ts +127 -0
  91. package/src/storage/domain/factories/README.md +138 -0
  92. package/src/storage/domain/factories/StoreFactory.ts +59 -0
  93. package/src/storage/domain/types/README.md +522 -0
  94. package/src/storage/domain/types/Store.ts +44 -0
  95. package/src/storage/domain/utils/CacheKeyGenerator.ts +66 -0
  96. package/src/storage/domain/utils/README.md +127 -0
  97. package/src/storage/domain/utils/__tests__/devUtils.test.ts +97 -0
  98. package/src/storage/domain/utils/devUtils.ts +37 -0
  99. package/src/storage/domain/value-objects/README.md +120 -0
  100. package/src/storage/domain/value-objects/StorageKey.ts +60 -0
  101. package/src/storage/index.ts +175 -0
  102. package/src/storage/infrastructure/README.md +165 -0
  103. package/src/storage/infrastructure/adapters/README.md +175 -0
  104. package/src/storage/infrastructure/adapters/StorageService.md +103 -0
  105. package/src/storage/infrastructure/adapters/StorageService.ts +49 -0
  106. package/src/storage/infrastructure/repositories/AsyncStorageRepository.ts +98 -0
  107. package/src/storage/infrastructure/repositories/BaseStorageOperations.ts +100 -0
  108. package/src/storage/infrastructure/repositories/BatchStorageOperations.ts +42 -0
  109. package/src/storage/infrastructure/repositories/README.md +121 -0
  110. package/src/storage/infrastructure/repositories/StringStorageOperations.ts +44 -0
  111. package/src/storage/infrastructure/repositories/__tests__/AsyncStorageRepository.test.ts +170 -0
  112. package/src/storage/infrastructure/repositories/__tests__/BaseStorageOperations.test.ts +201 -0
  113. package/src/storage/presentation/README.md +181 -0
  114. package/src/storage/presentation/hooks/CacheStorageOperations.ts +94 -0
  115. package/src/storage/presentation/hooks/README.md +128 -0
  116. package/src/storage/presentation/hooks/__tests__/usePersistentCache.test.ts +405 -0
  117. package/src/storage/presentation/hooks/__tests__/useStorage.test.ts +247 -0
  118. package/src/storage/presentation/hooks/__tests__/useStorageState.test.ts +293 -0
  119. package/src/storage/presentation/hooks/useCacheState.ts +53 -0
  120. package/src/storage/presentation/hooks/usePersistentCache.ts +154 -0
  121. package/src/storage/presentation/hooks/useStorage.ts +102 -0
  122. package/src/storage/presentation/hooks/useStorageState.ts +71 -0
  123. package/src/storage/presentation/hooks/useStore.ts +15 -0
  124. package/src/storage/types/README.md +103 -0
  125. package/src/theme/infrastructure/globalThemeStore.ts +1 -1
  126. package/src/theme/infrastructure/storage/ThemeStorage.ts +1 -1
  127. package/src/theme/infrastructure/stores/themeStore.ts +1 -1
  128. package/src/utilities/sharing/infrastructure/services/SharingService.ts +1 -1
@@ -0,0 +1,98 @@
1
+ /**
2
+ * AsyncStorage Repository
3
+ *
4
+ * Domain-Driven Design: Infrastructure implementation of IStorageRepository
5
+ * Adapts React Native AsyncStorage to domain interface using composition
6
+ */
7
+
8
+ import type { IStorageRepository } from '../../application/ports/IStorageRepository';
9
+ import type { StorageResult } from '../../domain/entities/StorageResult';
10
+ import { BaseStorageOperations } from './BaseStorageOperations';
11
+ import { StringStorageOperations } from './StringStorageOperations';
12
+ import { BatchStorageOperations } from './BatchStorageOperations';
13
+
14
+ /**
15
+ * AsyncStorage Repository Implementation
16
+ * Uses composition to follow Single Responsibility Principle
17
+ */
18
+ export class AsyncStorageRepository implements IStorageRepository {
19
+ private baseOps: BaseStorageOperations;
20
+ private stringOps: StringStorageOperations;
21
+ private batchOps: BatchStorageOperations;
22
+
23
+ constructor() {
24
+ this.baseOps = new BaseStorageOperations();
25
+ this.stringOps = new StringStorageOperations();
26
+ this.batchOps = new BatchStorageOperations();
27
+ }
28
+
29
+ /**
30
+ * Get item from AsyncStorage with type safety
31
+ */
32
+ async getItem<T>(key: string, defaultValue: T): Promise<StorageResult<T>> {
33
+ return this.baseOps.getItem(key, defaultValue);
34
+ }
35
+
36
+ /**
37
+ * Set item in AsyncStorage with automatic JSON serialization
38
+ */
39
+ async setItem<T>(key: string, value: T): Promise<StorageResult<T>> {
40
+ return this.baseOps.setItem(key, value);
41
+ }
42
+
43
+ /**
44
+ * Get string value (no JSON parsing)
45
+ */
46
+ async getString(key: string, defaultValue: string): Promise<StorageResult<string>> {
47
+ return this.stringOps.getString(key, defaultValue);
48
+ }
49
+
50
+ /**
51
+ * Set string value (no JSON serialization)
52
+ */
53
+ async setString(key: string, value: string): Promise<StorageResult<string>> {
54
+ return this.stringOps.setString(key, value);
55
+ }
56
+
57
+ /**
58
+ * Remove item from AsyncStorage
59
+ */
60
+ async removeItem(key: string): Promise<StorageResult<void>> {
61
+ return this.baseOps.removeItem(key);
62
+ }
63
+
64
+ /**
65
+ * Check if key exists in storage
66
+ */
67
+ async hasItem(key: string): Promise<boolean> {
68
+ return this.baseOps.hasItem(key);
69
+ }
70
+
71
+ /**
72
+ * Clear all AsyncStorage data
73
+ */
74
+ async clearAll(): Promise<StorageResult<void>> {
75
+ return this.baseOps.clearAll();
76
+ }
77
+
78
+ /**
79
+ * Get multiple items at once
80
+ */
81
+ async getMultiple(
82
+ keys: string[]
83
+ ): Promise<StorageResult<Record<string, string | null>>> {
84
+ return this.batchOps.getMultiple(keys);
85
+ }
86
+
87
+ /**
88
+ * Get all keys from storage
89
+ */
90
+ async getAllKeys(): Promise<StorageResult<string[]>> {
91
+ return this.batchOps.getAllKeys();
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Singleton instance
97
+ */
98
+ export const storageRepository = new AsyncStorageRepository();
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Base Storage Operations
3
+ *
4
+ * Core storage operations following Single Responsibility Principle
5
+ */
6
+
7
+ import AsyncStorage from '@react-native-async-storage/async-storage';
8
+ import type { StorageResult } from '../../domain/entities/StorageResult';
9
+ import { success, failure } from '../../domain/entities/StorageResult';
10
+ import {
11
+ StorageReadError,
12
+ StorageWriteError,
13
+ StorageDeleteError,
14
+ StorageSerializationError,
15
+ StorageDeserializationError,
16
+ } from '../../domain/errors/StorageError';
17
+ import { devWarn } from '../../domain/utils/devUtils';
18
+
19
+ /**
20
+ * Base storage operations implementation
21
+ */
22
+ export class BaseStorageOperations {
23
+ /**
24
+ * Get item from AsyncStorage with type safety
25
+ */
26
+ async getItem<T>(key: string, defaultValue: T): Promise<StorageResult<T>> {
27
+ try {
28
+ const value = await AsyncStorage.getItem(key);
29
+
30
+ if (value === null) {
31
+ return success(defaultValue);
32
+ }
33
+
34
+ try {
35
+ const parsed = JSON.parse(value) as T;
36
+ return success(parsed);
37
+ } catch (parseError) {
38
+ return failure(new StorageDeserializationError(key, parseError), defaultValue);
39
+ }
40
+ } catch (error) {
41
+ return failure(new StorageReadError(key, error), defaultValue);
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Set item in AsyncStorage with automatic JSON serialization
47
+ */
48
+ async setItem<T>(key: string, value: T): Promise<StorageResult<T>> {
49
+ try {
50
+ let serialized: string;
51
+ try {
52
+ serialized = JSON.stringify(value);
53
+ } catch (serializeError) {
54
+ return failure(new StorageSerializationError(key, serializeError));
55
+ }
56
+
57
+ await AsyncStorage.setItem(key, serialized);
58
+ return success(value);
59
+ } catch (error) {
60
+ return failure(new StorageWriteError(key, error));
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Remove item from AsyncStorage
66
+ */
67
+ async removeItem(key: string): Promise<StorageResult<void>> {
68
+ try {
69
+ await AsyncStorage.removeItem(key);
70
+ return success(undefined);
71
+ } catch (error) {
72
+ return failure(new StorageDeleteError(key, error));
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Check if key exists in storage
78
+ */
79
+ async hasItem(key: string): Promise<boolean> {
80
+ try {
81
+ const value = await AsyncStorage.getItem(key);
82
+ return value !== null;
83
+ } catch (error) {
84
+ devWarn(`BaseStorageOperations: Failed to check if key "${key}" exists`, error);
85
+ return false;
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Clear all AsyncStorage data
91
+ */
92
+ async clearAll(): Promise<StorageResult<void>> {
93
+ try {
94
+ await AsyncStorage.clear();
95
+ return success(undefined);
96
+ } catch (error) {
97
+ return failure(new StorageDeleteError('ALL_KEYS', error));
98
+ }
99
+ }
100
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Batch Storage Operations
3
+ *
4
+ * Batch operations following Single Responsibility Principle
5
+ */
6
+
7
+ import AsyncStorage from '@react-native-async-storage/async-storage';
8
+ import type { StorageResult } from '../../domain/entities/StorageResult';
9
+ import { success, failure } from '../../domain/entities/StorageResult';
10
+ import { StorageReadError } from '../../domain/errors/StorageError';
11
+
12
+ /**
13
+ * Batch storage operations for efficiency
14
+ */
15
+ export class BatchStorageOperations {
16
+ /**
17
+ * Get multiple items at once
18
+ */
19
+ async getMultiple(
20
+ keys: string[]
21
+ ): Promise<StorageResult<Record<string, string | null>>> {
22
+ try {
23
+ const pairs = await AsyncStorage.multiGet(keys);
24
+ const result = Object.fromEntries(pairs);
25
+ return success(result);
26
+ } catch (error) {
27
+ return failure(new StorageReadError('MULTIPLE_KEYS', error));
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Get all keys from storage
33
+ */
34
+ async getAllKeys(): Promise<StorageResult<string[]>> {
35
+ try {
36
+ const keys = await AsyncStorage.getAllKeys();
37
+ return success([...keys]);
38
+ } catch (error) {
39
+ return failure(new StorageReadError('ALL_KEYS', error));
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,121 @@
1
+ # Storage Repositories
2
+
3
+ Repository pattern implementation for data persistence with error handling.
4
+
5
+ ## Overview
6
+
7
+ AsyncStorageRepository provides storage operations with Result pattern for error handling. Located at `src/infrastructure/repositories/`.
8
+
9
+ ## Strategies
10
+
11
+ ### Result Pattern
12
+ - Return Result objects instead of throwing exceptions
13
+ - Use success/failure states for predictable error handling
14
+ - Include error details in failure results
15
+ - Allow graceful degradation when operations fail
16
+
17
+ ### Serialization Strategy
18
+ - Automatically serialize objects to JSON
19
+ - Deserialize with type safety using generics
20
+ - Handle circular reference errors gracefully
21
+ - Support all JSON-serializable types
22
+
23
+ ### Error Handling Strategy
24
+ - Categorize errors by type (read, write, serialization)
25
+ - Include key name in error context
26
+ - Preserve original error as cause
27
+ - Log errors for debugging
28
+
29
+ ### Performance Strategy
30
+ - Use parallel operations for batch operations
31
+ - Implement chunking for large datasets
32
+ - Avoid synchronous operations on main thread
33
+ - Cache frequently accessed values
34
+
35
+ ## Restrictions
36
+
37
+ ### Storage Operations
38
+ - DO NOT store non-JSON-serializable data (functions, class instances)
39
+ - DO NOT store circular references
40
+ - DO NOT use undefined values (use null instead)
41
+ - DO NOT store extremely large payloads (> 1MB) without chunking
42
+
43
+ ### Error Handling
44
+ - DO NOT ignore error states in Result objects
45
+ - DO NOT throw exceptions from repository methods
46
+ - DO NOT return null for missing keys (use defaultValue)
47
+ - DO NOT suppress error logging in production
48
+
49
+ ### Type Safety
50
+ - DO NOT use `any` type for stored values
51
+ - DO NOT skip type parameters on generic methods
52
+ - DO NOT assume Result is always successful
53
+ - DO NOT cast results without checking success flag
54
+
55
+ ### Performance
56
+ - DO NOT perform sequential operations in loops (use parallel)
57
+ - DO NOT read same key multiple times without caching
58
+ - DO NOT write to storage on every state change (debounce)
59
+ - DO NOT store redundant data
60
+
61
+ ## Rules
62
+
63
+ ### Interface Implementation
64
+ - MUST implement IStorageRepository interface completely
65
+ - MUST return StorageResult<T> for all methods
66
+ - MUST include error details in failure results
67
+ - MUST handle all exceptions internally
68
+
69
+ ### Method Signatures
70
+ - MUST provide generic type parameter for type safety
71
+ - MUST accept defaultValue parameter for getItem methods
72
+ - MUST return Promise for all async operations
73
+ - MUST preserve key names in error messages
74
+
75
+ ### Error Handling
76
+ - MUST wrap all storage operations in try-catch
77
+ - MUST return failure Result on errors
78
+ - MUST include error code and message
79
+ - MUST log errors before returning failure
80
+
81
+ ### Serialization
82
+ - MUST use JSON.stringify for setItem operations
83
+ - MUST use JSON.parse for getItem operations
84
+ - MUST handle JSON parsing errors
85
+ - MUST validate deserialized structure
86
+
87
+ ### Type Safety
88
+ - MUST enforce type parameter consistency
89
+ - MUST use type guards for runtime validation
90
+ - MUST provide type inference for return values
91
+ - MUST avoid type assertions when possible
92
+
93
+ ### Result Objects
94
+ - MUST set success flag to true or false
95
+ - MUST include data in success results
96
+ - MUST include error in failure results
97
+ - MUST check success flag before accessing data
98
+
99
+ ### Singleton Usage
100
+ - MUST use exported singleton instance
101
+ - MUST NOT create multiple repository instances
102
+ - MUST reset state between tests
103
+ - MUST clear storage in test setup
104
+
105
+ ### Testing
106
+ - MUST mock repository for unit tests
107
+ - MUST use real repository for integration tests
108
+ - MUST clear storage before each test
109
+ - MUST test both success and failure scenarios
110
+
111
+ ### Performance
112
+ - MUST use Promise.all for parallel operations
113
+ - MUST implement debouncing for frequent writes
114
+ - MUST use appropriate chunk sizes for large data
115
+ - MUST monitor storage size limits
116
+
117
+ ### Error Categories
118
+ - MUST use StorageReadError for read failures
119
+ - MUST use StorageWriteError for write failures
120
+ - MUST use StorageSerializationError for serialization failures
121
+ - MUST use StorageDeserializationError for parsing failures
@@ -0,0 +1,44 @@
1
+ /**
2
+ * String Storage Operations
3
+ *
4
+ * Specialized string operations following Single Responsibility Principle
5
+ */
6
+
7
+ import AsyncStorage from '@react-native-async-storage/async-storage';
8
+ import type { StorageResult } from '../../domain/entities/StorageResult';
9
+ import { success, failure } from '../../domain/entities/StorageResult';
10
+ import { StorageReadError, StorageWriteError } from '../../domain/errors/StorageError';
11
+
12
+ /**
13
+ * String-specific storage operations
14
+ */
15
+ export class StringStorageOperations {
16
+ /**
17
+ * Get string value (no JSON parsing)
18
+ */
19
+ async getString(key: string, defaultValue: string): Promise<StorageResult<string>> {
20
+ try {
21
+ const value = await AsyncStorage.getItem(key);
22
+
23
+ if (value === null) {
24
+ return success(defaultValue);
25
+ }
26
+
27
+ return success(value);
28
+ } catch (error) {
29
+ return failure(new StorageReadError(key, error), defaultValue);
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Set string value (no JSON serialization)
35
+ */
36
+ async setString(key: string, value: string): Promise<StorageResult<string>> {
37
+ try {
38
+ await AsyncStorage.setItem(key, value);
39
+ return success(value);
40
+ } catch (error) {
41
+ return failure(new StorageWriteError(key, error));
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,170 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ /**
3
+ * AsyncStorageRepository Tests
4
+ *
5
+ * Unit tests for AsyncStorageRepository
6
+ */
7
+
8
+ import { AsyncStorageRepository } from '../AsyncStorageRepository';
9
+ import { AsyncStorage } from '../../__tests__/mocks/asyncStorage.mock';
10
+
11
+ describe('AsyncStorageRepository', () => {
12
+ let repository: AsyncStorageRepository;
13
+
14
+ beforeEach(() => {
15
+ repository = new AsyncStorageRepository();
16
+ (AsyncStorage as any).__clear();
17
+ });
18
+
19
+ describe('Composition', () => {
20
+ it('should use composition pattern', () => {
21
+ expect(repository).toBeInstanceOf(AsyncStorageRepository);
22
+
23
+ // Test that all methods are available
24
+ expect(typeof repository.getItem).toBe('function');
25
+ expect(typeof repository.setItem).toBe('function');
26
+ expect(typeof repository.getString).toBe('function');
27
+ expect(typeof repository.setString).toBe('function');
28
+ expect(typeof repository.removeItem).toBe('function');
29
+ expect(typeof repository.hasItem).toBe('function');
30
+ expect(typeof repository.clearAll).toBe('function');
31
+ expect(typeof repository.getMultiple).toBe('function');
32
+ expect(typeof repository.getAllKeys).toBe('function');
33
+ });
34
+ });
35
+
36
+ describe('Delegation', () => {
37
+ it('should delegate getItem to BaseStorageOperations', async () => {
38
+ const key = 'test-key';
39
+ const defaultValue = 'default';
40
+ const expectedValue = 'test-value';
41
+
42
+ await AsyncStorage.setItem(key, JSON.stringify(expectedValue));
43
+
44
+ const result = await repository.getItem(key, defaultValue);
45
+
46
+ expect(result.success).toBe(true);
47
+ expect(result.data).toBe(expectedValue);
48
+ });
49
+
50
+ it('should delegate setItem to BaseStorageOperations', async () => {
51
+ const key = 'test-key';
52
+ const value = 'test-value';
53
+
54
+ const result = await repository.setItem(key, value);
55
+
56
+ expect(result.success).toBe(true);
57
+ expect(result.data).toBe(value);
58
+ });
59
+
60
+ it('should delegate getString to StringStorageOperations', async () => {
61
+ const key = 'test-key';
62
+ const defaultValue = 'default';
63
+ const expectedValue = 'test-string';
64
+
65
+ await AsyncStorage.setItem(key, expectedValue);
66
+
67
+ const result = await repository.getString(key, defaultValue);
68
+
69
+ expect(result.success).toBe(true);
70
+ expect(result.data).toBe(expectedValue);
71
+ });
72
+
73
+ it('should delegate setString to StringStorageOperations', async () => {
74
+ const key = 'test-key';
75
+ const value = 'test-string';
76
+
77
+ const result = await repository.setString(key, value);
78
+
79
+ expect(result.success).toBe(true);
80
+ expect(result.data).toBe(value);
81
+ });
82
+
83
+ it('should delegate removeItem to BaseStorageOperations', async () => {
84
+ const key = 'test-key';
85
+
86
+ await AsyncStorage.setItem(key, 'test-value');
87
+
88
+ const result = await repository.removeItem(key);
89
+
90
+ expect(result.success).toBe(true);
91
+ });
92
+
93
+ it('should delegate hasItem to BaseStorageOperations', async () => {
94
+ const key = 'test-key';
95
+
96
+ await AsyncStorage.setItem(key, 'test-value');
97
+
98
+ const exists = await repository.hasItem(key);
99
+
100
+ expect(exists).toBe(true);
101
+ });
102
+
103
+ it('should delegate clearAll to BaseStorageOperations', async () => {
104
+ await AsyncStorage.setItem('key1', 'value1');
105
+ await AsyncStorage.setItem('key2', 'value2');
106
+
107
+ const result = await repository.clearAll();
108
+
109
+ expect(result.success).toBe(true);
110
+ });
111
+
112
+ it('should delegate getMultiple to BatchStorageOperations', async () => {
113
+ const keys = ['key1', 'key2'];
114
+
115
+ await AsyncStorage.setItem('key1', 'value1');
116
+ await AsyncStorage.setItem('key2', 'value2');
117
+
118
+ const result = await repository.getMultiple(keys);
119
+
120
+ expect(result.success).toBe(true);
121
+ expect(result.data).toEqual({
122
+ key1: 'value1',
123
+ key2: 'value2'
124
+ });
125
+ });
126
+
127
+ it('should delegate getAllKeys to BatchStorageOperations', async () => {
128
+ await AsyncStorage.setItem('key1', 'value1');
129
+ await AsyncStorage.setItem('key2', 'value2');
130
+
131
+ const result = await repository.getAllKeys();
132
+
133
+ expect(result.success).toBe(true);
134
+ expect(result.data).toEqual(expect.arrayContaining(['key1', 'key2']));
135
+ });
136
+ });
137
+
138
+ describe('Error Handling', () => {
139
+ it('should handle errors from delegated operations', async () => {
140
+ const key = 'test-key';
141
+
142
+ // Mock error in AsyncStorage
143
+ (AsyncStorage.getItem as jest.Mock).mockRejectedValue(new Error('Storage error'));
144
+
145
+ const result = await repository.getItem(key, 'default');
146
+
147
+ expect(result.success).toBe(false);
148
+ expect(result.error).toBeDefined();
149
+ });
150
+ });
151
+
152
+ describe('Type Safety', () => {
153
+ it('should maintain type safety for generic methods', async () => {
154
+ interface TestData {
155
+ id: number;
156
+ name: string;
157
+ }
158
+
159
+ const key = 'typed-key';
160
+ const data: TestData = { id: 1, name: 'test' };
161
+
162
+ const setResult = await repository.setItem<TestData>(key, data);
163
+ const getResult = await repository.getItem<TestData>(key, { id: 0, name: '' });
164
+
165
+ expect(setResult.success).toBe(true);
166
+ expect(getResult.success).toBe(true);
167
+ expect(getResult.data).toEqual(data);
168
+ });
169
+ });
170
+ });