@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,175 @@
1
+ /**
2
+ * Storage Domain - Public API
3
+ *
4
+ * Domain-Driven Design (DDD) Architecture
5
+ *
6
+ * This is the SINGLE SOURCE OF TRUTH for all storage operations.
7
+ * ALL imports from the storage domain MUST go through this file.
8
+ *
9
+ * Architecture:
10
+ * - domain: Entities, value objects, errors (business logic)
11
+ * - application: Ports (interfaces), use cases (not needed for simple CRUD)
12
+ * - infrastructure: Repository implementation (AsyncStorage adapter)
13
+ * - presentation: Hooks (React integration)
14
+ *
15
+ * Usage:
16
+ * import { useStorage, useStorageState, createStore } from '@umituz/react-native-design-system';
17
+ */
18
+
19
+ // =============================================================================
20
+ // DOMAIN LAYER - Business Logic
21
+ // =============================================================================
22
+
23
+ export {
24
+ StorageKey,
25
+ createUserKey,
26
+ createAppKey,
27
+ } from './domain/value-objects/StorageKey';
28
+
29
+ export type { DynamicStorageKey } from './domain/value-objects/StorageKey';
30
+
31
+ export {
32
+ StorageError,
33
+ StorageReadError,
34
+ StorageWriteError,
35
+ StorageDeleteError,
36
+ StorageSerializationError,
37
+ StorageDeserializationError,
38
+ } from './domain/errors/StorageError';
39
+
40
+ export type { StorageResult } from './domain/entities/StorageResult';
41
+
42
+ export {
43
+ success,
44
+ failure,
45
+ unwrap,
46
+ map,
47
+ isSuccess,
48
+ isFailure,
49
+ } from './domain/entities/StorageResult';
50
+
51
+ // =============================================================================
52
+ // DOMAIN LAYER - Cached Value Entity
53
+ // =============================================================================
54
+
55
+ export type { CachedValue } from './domain/entities/CachedValue';
56
+
57
+ export {
58
+ createCachedValue,
59
+ isCacheExpired,
60
+ getRemainingTTL,
61
+ getCacheAge,
62
+ } from './domain/entities/CachedValue';
63
+
64
+ // =============================================================================
65
+ // DOMAIN LAYER - Cache Utilities
66
+ // =============================================================================
67
+
68
+ export {
69
+ generateCacheKey,
70
+ generateListCacheKey,
71
+ parseCacheKey,
72
+ isCacheKey,
73
+ } from './domain/utils/CacheKeyGenerator';
74
+
75
+ // =============================================================================
76
+ // DOMAIN LAYER - Cache Constants
77
+ // =============================================================================
78
+
79
+ export { TIME_MS, DEFAULT_TTL, CACHE_VERSION } from './domain/constants/CacheDefaults';
80
+
81
+ // =============================================================================
82
+ // DOMAIN LAYER - Development Utilities
83
+ // =============================================================================
84
+
85
+ export { isDev, devWarn, devError, devLog } from './domain/utils/devUtils';
86
+
87
+ // =============================================================================
88
+ // DOMAIN LAYER - Store Types
89
+ // =============================================================================
90
+
91
+ export type {
92
+ StoreConfig,
93
+ PersistedState,
94
+ SetState,
95
+ GetState,
96
+ ActionsCreator,
97
+ } from './domain/types/Store';
98
+
99
+ // =============================================================================
100
+ // DOMAIN LAYER - Store Factory
101
+ // =============================================================================
102
+
103
+ export { createStore } from './domain/factories/StoreFactory';
104
+
105
+ // =============================================================================
106
+ // ZUSTAND - Type Re-exports for Compatibility
107
+ // =============================================================================
108
+
109
+ export type { StoreApi, UseBoundStore } from 'zustand';
110
+ export type { StateCreator, StoreMutatorIdentifier } from 'zustand/vanilla';
111
+
112
+ // =============================================================================
113
+ // APPLICATION LAYER - Ports
114
+ // =============================================================================
115
+
116
+ export type { IStorageRepository } from './application/ports/IStorageRepository';
117
+
118
+ // =============================================================================
119
+ // INFRASTRUCTURE LAYER - Implementation
120
+ // =============================================================================
121
+
122
+ export {
123
+ AsyncStorageRepository,
124
+ storageRepository,
125
+ } from './infrastructure/repositories/AsyncStorageRepository';
126
+
127
+ export {
128
+ storageService,
129
+ type StateStorage,
130
+ } from './infrastructure/adapters/StorageService';
131
+
132
+ // =============================================================================
133
+ // PRESENTATION LAYER - Hooks
134
+ // =============================================================================
135
+
136
+ export { useStorage } from './presentation/hooks/useStorage';
137
+ export { useStorageState } from './presentation/hooks/useStorageState';
138
+ export { useStore } from './presentation/hooks/useStore';
139
+
140
+ export {
141
+ usePersistentCache,
142
+ type PersistentCacheOptions,
143
+ type PersistentCacheResult,
144
+ } from './presentation/hooks/usePersistentCache';
145
+
146
+ export { useCacheState } from './presentation/hooks/useCacheState';
147
+ export { CacheStorageOperations } from './presentation/hooks/CacheStorageOperations';
148
+
149
+ // =============================================================================
150
+ // IN-MEMORY CACHE LAYER (Merged from @umituz/react-native-cache)
151
+ // =============================================================================
152
+
153
+ export { Cache } from './cache/domain/Cache';
154
+ export { CacheManager, cacheManager } from './cache/domain/CacheManager';
155
+ export { CacheStatsTracker } from './cache/domain/CacheStatsTracker';
156
+ export { PatternMatcher } from './cache/domain/PatternMatcher';
157
+ export { ErrorHandler, CacheError } from './cache/domain/ErrorHandler';
158
+ export { TTLCache } from './cache/infrastructure/TTLCache';
159
+
160
+ export type {
161
+ CacheEntry,
162
+ CacheConfig,
163
+ CacheStats,
164
+ EvictionStrategy,
165
+ } from './cache/domain/types/Cache';
166
+
167
+ export type { EvictionStrategy as IEvictionStrategy } from './cache/domain/strategies/EvictionStrategy';
168
+
169
+ export { LRUStrategy } from './cache/domain/strategies/LRUStrategy';
170
+ export { LFUStrategy } from './cache/domain/strategies/LFUStrategy';
171
+ export { FIFOStrategy } from './cache/domain/strategies/FIFOStrategy';
172
+ export { TTLStrategy as TTLEvictionStrategy } from './cache/domain/strategies/TTLStrategy';
173
+
174
+ export { useCache } from './cache/presentation/useCache';
175
+ export { useCachedValue } from './cache/presentation/useCachedValue';
@@ -0,0 +1,165 @@
1
+ # Infrastructure Layer
2
+
3
+ External service adapters and storage repository implementations.
4
+
5
+ ## Overview
6
+
7
+ Infrastructure layer containing concrete implementations of storage operations. Located at `src/infrastructure/`.
8
+
9
+ ## Directory Structure
10
+
11
+ - `adapters/` - External service adapters for Zustand persist middleware
12
+ - `repositories/` - Storage repository implementations with Result pattern
13
+
14
+ ## Strategies
15
+
16
+ ### Adapter Implementation
17
+ - Use StorageService adapter for Zustand persist middleware
18
+ - Implement StateStorage interface for Zustand integration
19
+ - Support AsyncStorage, MMKV, and SecureStore adapters
20
+ - Enable custom adapter creation for different storage backends
21
+
22
+ ### Repository Pattern
23
+ - Use AsyncStorageRepository for primary storage operations
24
+ - Implement Result pattern for type-safe error handling
25
+ - Support generic type parameters for type safety
26
+ - Enable serialization/deserialization of complex objects
27
+
28
+ ### Storage Adapters
29
+ - Use storageService for Zustand persist integration
30
+ - Create custom adapters for StateStorage interface
31
+ - Support SecureStore for sensitive data (tokens, credentials)
32
+ - Enable pluggable storage backends
33
+
34
+ ### Error Handling
35
+ - Wrap all storage operations in try-catch blocks
36
+ - Return Result type instead of throwing exceptions
37
+ - Preserve original error context in cause property
38
+ - Support hierarchical error types for specific failures
39
+
40
+ ### Serialization Strategy
41
+ - Use JSON.stringify for object serialization
42
+ - Use JSON.parse for deserialization with type safety
43
+ - Handle circular reference errors
44
+ - Support custom serialization for special types
45
+
46
+ ## Restrictions
47
+
48
+ ### Adapter Implementation
49
+ - DO NOT create adapters without implementing StateStorage interface
50
+ - DO NOT mix different storage backends in single adapter
51
+ - DO NOT skip error handling in adapter methods
52
+ - DO NOT store sensitive data without encryption
53
+
54
+ ### Repository Usage
55
+ - DO NOT create new repository instances (use singleton)
56
+ - DO NOT bypass Result pattern error handling
57
+ - DO NOT use type assertions for type safety
58
+ - DO NOT ignore error codes from storage operations
59
+
60
+ ### Storage Operations
61
+ - DO NOT perform operations without error handling
62
+ - DO NOT assume storage operations succeed
63
+ - DO NOT mix string and object storage methods
64
+ - DO NOT forget to handle null/undefined cases
65
+
66
+ ### Error Handling
67
+ - DO NOT catch and ignore errors silently
68
+ - DO NOT expose sensitive data in error messages
69
+ - DO NOT lose error context when wrapping errors
70
+ - DO NOT create infinite error loops
71
+
72
+ ### Serialization
73
+ - DO NOT serialize unsupported types (functions, symbols)
74
+ - DO NOT assume deserialization always succeeds
75
+ - DO NOT store raw data without validation
76
+ - DO NOT mix data formats in storage
77
+
78
+ ## Rules
79
+
80
+ ### Adapter Implementation
81
+ - MUST implement StateStorage interface for Zustand
82
+ - MUST provide getItem, setItem, removeItem methods
83
+ - MUST return Promise<string | null> from getItem
84
+ - MUST return Promise<void> from setItem and removeItem
85
+ - MUST handle errors gracefully in all methods
86
+
87
+ ### AsyncStorageRepository
88
+ - MUST use singleton pattern (export storageRepository)
89
+ - MUST implement IStorageRepository interface
90
+ - MUST return StorageResult<T> from all methods
91
+ - MUST support generic type parameters
92
+ - MUST serialize objects with JSON.stringify
93
+ - MUST deserialize with JSON.parse and type validation
94
+ - MUST provide default value parameter for getItem
95
+
96
+ ### Method Signatures
97
+ - MUST provide getItem<T>(key, defaultValue): Promise<StorageResult<T>>
98
+ - MUST provide setItem<T>(key, value): Promise<StorageResult<void>>
99
+ - MUST provide getString(key, defaultValue): Promise<StorageResult<string>>
100
+ - MUST provide setString(key, value): Promise<StorageResult<void>>
101
+ - MUST provide removeItem(key): Promise<StorageResult<void>>
102
+ - MUST provide hasItem(key): Promise<boolean>
103
+ - MUST provide clearAll(): Promise<StorageResult<void>>
104
+
105
+ ### Error Handling
106
+ - MUST wrap all storage operations in try-catch
107
+ - MUST return failure() with StorageError on catch
108
+ - MUST preserve original error in cause property
109
+ - MUST include storage key in error context
110
+ - MUST use specific error types (StorageReadError, StorageWriteError)
111
+ - MUST not expose sensitive data in error messages
112
+
113
+ ### Result Pattern
114
+ - MUST return success(data) on successful operations
115
+ - MUST return failure(error) on failed operations
116
+ - MUST check result.success before accessing result.data
117
+ - MUST handle result.error when success is false
118
+ - MUST not throw exceptions from repository methods
119
+
120
+ ### Type Safety
121
+ - MUST use generic type parameters for all value operations
122
+ - MUST infer types from default value parameter
123
+ - MUST not use type assertions for type safety
124
+ - MUST validate types at runtime when deserializing
125
+ - MUST support complex types (objects, arrays)
126
+
127
+ ### Singleton Pattern
128
+ - MUST export single storageRepository instance
129
+ - MUST use singleton for production code
130
+ - MUST enable instance creation for testing
131
+ - MUST not create multiple instances in production
132
+
133
+ ### Custom Adapters
134
+ - MUST implement StateStorage interface
135
+ - MUST handle all required methods
136
+ - MUST support async operations
137
+ - MUST provide error handling
138
+ - MUST be compatible with Zustand persist
139
+
140
+ ### SecureStore Integration
141
+ - MUST use SecureStore for sensitive data only
142
+ - MUST create separate adapter for SecureStore
143
+ - MUST not mix secure and non-secure storage
144
+ - MUST handle SecureStore-specific errors
145
+
146
+ ### Testing Support
147
+ - MUST enable mocking for all methods
148
+ - MUST provide test double support
149
+ - MUST clear state between tests
150
+ - MUST not have hidden dependencies
151
+ - MUST support dependency injection
152
+
153
+ ### Export Rules
154
+ - MUST export storageRepository singleton
155
+ - MUST export AsyncStorageRepository class
156
+ - MUST export storageService adapter
157
+ - MUST export all error types
158
+ - MUST export interface types
159
+
160
+ ### Documentation
161
+ - MUST document all public methods
162
+ - MUST specify error types thrown
163
+ - MUST provide usage examples in separate files
164
+ - MUST warn about common mistakes
165
+ - MUST not include code in README files
@@ -0,0 +1,175 @@
1
+ # Storage Adapters
2
+
3
+ Adapters for integrating Zustand persist middleware with various storage backends.
4
+
5
+ ## Overview
6
+
7
+ Storage adapter implementations for Zustand persist middleware. Located at `src/infrastructure/adapters/`.
8
+
9
+ ## Strategies
10
+
11
+ ### Adapter Pattern
12
+ - Use StorageService adapter for AsyncStorage integration
13
+ - Implement StateStorage interface for Zustand compatibility
14
+ - Support multiple storage backends (AsyncStorage, MMKV, SecureStore)
15
+ - Enable custom adapter creation for specific needs
16
+
17
+ ### Storage Backend Selection
18
+ - Use AsyncStorage for general-purpose storage
19
+ - Use MMKV for high-performance key-value storage
20
+ - Use SecureStore for sensitive data (tokens, credentials)
21
+ - Use SQLite for complex relational data
22
+ - Use file system for large data or binary files
23
+
24
+ ### Adapter Composition
25
+ - Use namespaced adapters for key isolation
26
+ - Use hybrid adapters for multi-level caching
27
+ - Use encrypted adapters for data security
28
+ - Use migrating adapters for version management
29
+
30
+ ### Error Handling
31
+ - Wrap all storage operations in try-catch blocks
32
+ - Return null on read failures for graceful degradation
33
+ - Log errors for debugging
34
+ - Implement retry logic for transient failures
35
+
36
+ ## Restrictions
37
+
38
+ ### Adapter Implementation
39
+ - DO NOT create adapters without implementing StateStorage interface
40
+ - DO NOT mix synchronous and asynchronous operations
41
+ - DO NOT ignore errors in adapter methods
42
+ - DO NOT create infinite loops in error handlers
43
+
44
+ ### Storage Selection
45
+ - DO NOT use SecureStore for large data
46
+ - DO NOT use AsyncStorage for frequently accessed data
47
+ - DO NOT use file system for simple key-value storage
48
+ - DO NOT use sensitive storage for non-sensitive data
49
+
50
+ ### Adapter Usage
51
+ - DO NOT use the same adapter instance for different purposes
52
+ - DO NOT create adapters without proper error handling
53
+ - DO NOT share adapters between incompatible stores
54
+ - DO NOT forget to clean up resources
55
+
56
+ ### Custom Adapters
57
+ - DO NOT implement custom adapters without necessity
58
+ - DO NOT skip implementing required interface methods
59
+ - DO NOT create adapters with hidden dependencies
60
+ - DO NOT use adapters without testing
61
+
62
+ ## Rules
63
+
64
+ ### StateStorage Interface
65
+ - MUST implement getItem(key): Promise<string | null>
66
+ - MUST implement setItem(key, value): Promise<void>
67
+ - MUST implement removeItem(key): Promise<void>
68
+ - MUST handle all errors gracefully
69
+ - MUST return Promise for all methods
70
+ - MUST be compatible with Zustand persist middleware
71
+
72
+ ### StorageService Adapter
73
+ - MUST use AsyncStorage for storage operations
74
+ - MUST handle serialization/deserialization
75
+ - MUST provide null for missing keys
76
+ - MUST not throw exceptions for missing data
77
+ - MUST be the default adapter for Zustand stores
78
+
79
+ ### Custom Adapter Creation
80
+ - MUST implement StateStorage interface completely
81
+ - MUST handle all three required methods
82
+ - MUST provide async method implementations
83
+ - MUST include error handling
84
+ - MUST be compatible with Zustand persist
85
+
86
+ ### SecureStore Adapter
87
+ - MUST use expo-secure-store for implementation
88
+ - MUST handle SecureStore-specific errors
89
+ - MUST be used only for sensitive data
90
+ - MUST not store large amounts of data
91
+ - MUST provide proper error messages
92
+
93
+ ### MMKV Adapter
94
+ - MUST use react-native-mmkv for implementation
95
+ - MUST initialize MMKV instance properly
96
+ - MUST handle type conversions
97
+ - MUST provide high-performance storage
98
+ - MUST support synchronous operations if needed
99
+
100
+ ### SQLite Adapter
101
+ - MUST initialize database schema on first use
102
+ - MUST use transactions for data integrity
103
+ - MUST handle database connection errors
104
+ - MUST use parameterized queries
105
+ - MUST close connections properly
106
+
107
+ ### File System Adapter
108
+ - MUST validate file paths
109
+ - MUST handle file system permissions
110
+ - MUST provide proper error messages
111
+ - MUST clean up temporary files
112
+ - MUST handle concurrent access safely
113
+
114
+ ### Encrypted Adapter
115
+ - MUST use strong encryption algorithms
116
+ - MUST properly manage encryption keys
117
+ - MUST handle encryption/decryption errors
118
+ - MUST not expose keys in logs
119
+ - MUST use secure key storage
120
+
121
+ ### Namespaced Adapter
122
+ - MUST prefix all keys with namespace
123
+ - MUST use consistent separator (:) in keys
124
+ - MUST enable key isolation between stores
125
+ - MUST prevent key collisions
126
+ - MUST be composable with other adapters
127
+
128
+ ### Hybrid Adapter
129
+ - MUST define clear fallback strategy
130
+ - MUST handle consistency between storages
131
+ - MUST implement read-through caching
132
+ - MUST implement write-through caching
133
+ - MUST handle partial failures gracefully
134
+
135
+ ### Migrating Adapter
136
+ - MUST support version management
137
+ - MUST migrate data on read
138
+ - MUST clean up old data after migration
139
+ - MUST handle migration failures
140
+ - MUST be backward compatible
141
+
142
+ ### Error Handling
143
+ - MUST catch all exceptions in adapter methods
144
+ - MUST return null on read failures
145
+ - MUST log errors for debugging
146
+ - MUST not expose sensitive data in errors
147
+ - MUST provide meaningful error context
148
+
149
+ ### Performance Considerations
150
+ - MUST minimize storage operations
151
+ - MUST batch operations when possible
152
+ - MUST use appropriate storage for data size
153
+ - MUST consider synchronous vs asynchronous operations
154
+ - MUST optimize for read-heavy or write-heavy patterns
155
+
156
+ ### Testing Support
157
+ - MUST enable adapter mocking
158
+ - MUST provide test implementations
159
+ - MUST support dependency injection
160
+ - MUST clear state between tests
161
+ - MUST not have hidden dependencies
162
+
163
+ ### Export Rules
164
+ - MUST export storageService as default adapter
165
+ - MUST export adapter types
166
+ - MUST export adapter utilities
167
+ - MUST document adapter behavior
168
+ - MUST provide usage examples separately
169
+
170
+ ### Documentation
171
+ - MUST document all custom adapters
172
+ - MUST specify storage backend requirements
173
+ - MUST explain adapter behavior
174
+ - MUST warn about limitations
175
+ - MUST not include code in README files
@@ -0,0 +1,103 @@
1
+ # Storage Service
2
+
3
+ Zustand persist middleware adapter for AsyncStorage integration.
4
+
5
+ ## Overview
6
+
7
+ StorageService adapts AsyncStorage for use with Zustand's persist middleware, providing automatic state persistence. Located at `src/infrastructure/adapters/StorageService.ts`.
8
+
9
+ ## Strategies
10
+
11
+ ### Storage Adapter Pattern
12
+ - Implement StateStorage interface for Zustand compatibility
13
+ - Wrap AsyncStorage operations in try-catch blocks
14
+ - Provide graceful error handling with logging
15
+ - Return null/undefined on errors to prevent app crashes
16
+
17
+ ### Error Handling Strategy
18
+ - Log all storage errors with context
19
+ - Return null on getItem errors
20
+ - Throw errors on setItem/removeItem for persist middleware
21
+ - Include key name in error messages
22
+
23
+ ### Custom Adapters
24
+ - Create SecureStore adapter for sensitive data (tokens, credentials)
25
+ - Create encrypted storage adapter for high-security requirements
26
+ - Create namespaced adapters for data isolation
27
+ - Create platform-specific adapters (web localStorage vs native)
28
+
29
+ ## Restrictions
30
+
31
+ ### Storage Operations
32
+ - DO NOT use StorageService outside Zustand persist middleware
33
+ - DO NOT store non-serializable data (functions, class instances)
34
+ - DO NOT store large payloads (> 1MB) without chunking strategy
35
+ - DO NOT mix data types in same storage key
36
+
37
+ ### Error Handling
38
+ - DO NOT ignore storage errors in production
39
+ - DO NOT throw on getItem errors (return null instead)
40
+ - DO NOT suppress setItem/removeItem errors
41
+ - DO NOT log sensitive data in error messages
42
+
43
+ ### Custom Adapters
44
+ - DO NOT create adapters without implementing StateStorage interface
45
+ - DO NOT use SecureStore for non-sensitive data (performance)
46
+ - DO NOT use encryption without secure key management
47
+ - DO NOT create platform-specific adapters without Platform checks
48
+
49
+ ## Rules
50
+
51
+ ### Interface Implementation
52
+ - MUST implement `getItem(key: string): Promise<string | null>`
53
+ - MUST implement `setItem(key: string, value: string): Promise<void>`
54
+ - MUST implement `removeItem(key: string): Promise<void>`
55
+ - MUST return Promise for all methods
56
+
57
+ ### Error Handling
58
+ - MUST wrap all AsyncStorage operations in try-catch
59
+ - MUST log errors with key name for debugging
60
+ - MUST return null on getItem errors
61
+ - MUST throw original error on setItem/removeItem errors
62
+
63
+ ### Store Configuration
64
+ - MUST use unique store names across all stores
65
+ - MUST pass storageService as storage option
66
+ - MUST specify store name in persist config
67
+ - MUST handle migration when store schema changes
68
+
69
+ ### Multiple Stores
70
+ - MUST use different store names for different stores
71
+ - MUST ensure store names are unique across app
72
+ - MUST document each store's purpose
73
+ - MUST consider storage key conflicts
74
+
75
+ ### Custom Adapter Creation
76
+ - MUST implement complete StateStorage interface
77
+ - MUST handle errors consistently with base adapter
78
+ - MUST log errors with context
79
+ - MUST document adapter purpose and security model
80
+
81
+ ### Secure Storage
82
+ - MUST use SecureStore for sensitive data only
83
+ - MUST document what data is secure vs regular storage
84
+ - MUST handle SecureStore unavailability (web platform)
85
+ - MUST provide fallback for secure storage failures
86
+
87
+ ### Testing
88
+ - MUST mock StorageService in tests
89
+ - MUST clear storage in test setup
90
+ - MUST test error scenarios
91
+ - MUST test serialization/deserialization
92
+
93
+ ### Version Control
94
+ - MUST increment version when store schema changes
95
+ - MUST implement migrate function for schema changes
96
+ - MUST test migration with old persisted data
97
+ - MUST document migration path
98
+
99
+ ### Performance
100
+ - MUST consider storage operation performance
101
+ - MUST avoid frequent setItem calls (debounce if needed)
102
+ - MUST batch operations when possible
103
+ - MUST monitor storage size limits
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Storage Service
3
+ *
4
+ * Zustand persist middleware compatible StateStorage implementation.
5
+ * Uses AsyncStorage under the hood for React Native persistence.
6
+ */
7
+
8
+ import AsyncStorage from '@react-native-async-storage/async-storage';
9
+ import { devWarn } from '../../domain/utils/devUtils';
10
+
11
+ /**
12
+ * StateStorage interface for Zustand persist middleware
13
+ */
14
+ export interface StateStorage {
15
+ getItem: (name: string) => string | null | Promise<string | null>;
16
+ setItem: (name: string, value: string) => void | Promise<void>;
17
+ removeItem: (name: string) => void | Promise<void>;
18
+ }
19
+
20
+ /**
21
+ * Storage service for Zustand persist middleware
22
+ * Direct AsyncStorage implementation with proper error handling
23
+ */
24
+ export const storageService: StateStorage = {
25
+ getItem: async (name: string): Promise<string | null> => {
26
+ try {
27
+ return await AsyncStorage.getItem(name);
28
+ } catch (error) {
29
+ devWarn(`StorageService: Failed to get item "${name}"`, error);
30
+ return null;
31
+ }
32
+ },
33
+
34
+ setItem: async (name: string, value: string): Promise<void> => {
35
+ try {
36
+ await AsyncStorage.setItem(name, value);
37
+ } catch (error) {
38
+ devWarn(`StorageService: Failed to set item "${name}"`, error);
39
+ }
40
+ },
41
+
42
+ removeItem: async (name: string): Promise<void> => {
43
+ try {
44
+ await AsyncStorage.removeItem(name);
45
+ } catch (error) {
46
+ devWarn(`StorageService: Failed to remove item "${name}"`, error);
47
+ }
48
+ },
49
+ };