@umituz/react-native-storage 2.6.23 → 2.6.25
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 +137 -0
- package/package.json +2 -1
- package/src/README.md +185 -0
- package/src/application/README.md +158 -0
- package/src/application/ports/README.md +127 -0
- package/src/cache/README.md +154 -0
- package/src/cache/domain/CacheManager.md +83 -0
- package/src/cache/domain/CacheStatsTracker.md +169 -0
- package/src/cache/domain/CachedValue.md +97 -0
- package/src/cache/domain/ErrorHandler.md +99 -0
- package/src/cache/domain/PatternMatcher.md +122 -0
- package/src/cache/domain/README.md +118 -0
- package/src/cache/domain/strategies/README.md +117 -0
- package/src/cache/domain/types/README.md +107 -0
- package/src/cache/infrastructure/README.md +126 -0
- package/src/cache/presentation/README.md +123 -0
- package/src/domain/README.md +128 -0
- package/src/domain/constants/README.md +105 -0
- package/src/domain/entities/README.md +109 -0
- package/src/domain/errors/README.md +126 -0
- package/src/domain/factories/README.md +138 -0
- package/src/domain/types/README.md +522 -0
- package/src/domain/utils/README.md +127 -0
- package/src/domain/value-objects/README.md +120 -0
- package/src/index.ts +0 -0
- package/src/infrastructure/README.md +165 -0
- package/src/infrastructure/adapters/README.md +175 -0
- package/src/infrastructure/adapters/StorageService.md +103 -0
- package/src/infrastructure/repositories/README.md +121 -0
- package/src/presentation/README.md +181 -0
- package/src/presentation/hooks/README.md +128 -0
- package/src/types/README.md +103 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Value Objects
|
|
2
|
+
|
|
3
|
+
Type-safe storage key value objects for scoped data organization.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Value objects for creating structured, type-safe storage keys with scoping. Located at `src/domain/value-objects/`.
|
|
8
|
+
|
|
9
|
+
## Strategies
|
|
10
|
+
|
|
11
|
+
### Key Organization
|
|
12
|
+
- Use factory functions for key creation
|
|
13
|
+
- Organize keys by scope (app, user, organization)
|
|
14
|
+
- Use consistent separator (`:`) throughout
|
|
15
|
+
- Enable type-safe key generation
|
|
16
|
+
|
|
17
|
+
### Scoping Strategy
|
|
18
|
+
- Use app scope for application-wide data
|
|
19
|
+
- Use user scope for user-specific data
|
|
20
|
+
- Use organization scope for organization data
|
|
21
|
+
- Create custom scopes for specific use cases
|
|
22
|
+
|
|
23
|
+
### Type Safety
|
|
24
|
+
- Use generic type parameters for section names
|
|
25
|
+
- Enable type inference for key structure
|
|
26
|
+
- Prevent key collisions through naming
|
|
27
|
+
- Support key pattern matching
|
|
28
|
+
|
|
29
|
+
### Key Formats
|
|
30
|
+
- Follow consistent format: `scope:id:section`
|
|
31
|
+
- Use descriptive section names
|
|
32
|
+
- Document key patterns in code comments
|
|
33
|
+
- Support pattern-based invalidation
|
|
34
|
+
|
|
35
|
+
## Restrictions
|
|
36
|
+
|
|
37
|
+
### Key Creation
|
|
38
|
+
- DO NOT create keys without factory functions
|
|
39
|
+
- DO NOT use dynamic strings as keys
|
|
40
|
+
- DO NOT mix different key scopes
|
|
41
|
+
- DO NOT create ambiguous key structures
|
|
42
|
+
|
|
43
|
+
### Key Formats
|
|
44
|
+
- DO NOT use inconsistent separators
|
|
45
|
+
- DO NOT use empty section names
|
|
46
|
+
- DO NOT use special characters in keys
|
|
47
|
+
- DO NOT create overly deep hierarchies
|
|
48
|
+
|
|
49
|
+
### Type Safety
|
|
50
|
+
- DO NOT use `any` for key sections
|
|
51
|
+
- DO NOT skip type parameters
|
|
52
|
+
- DO NOT cast keys to strings prematurely
|
|
53
|
+
- DO NOT mix different key types
|
|
54
|
+
|
|
55
|
+
## Rules
|
|
56
|
+
|
|
57
|
+
### Factory Functions
|
|
58
|
+
- MUST use createUserKey() for user data
|
|
59
|
+
- MUST use createAppKey() for app data
|
|
60
|
+
- MUST use createUserScopedKey() for user-scoped data
|
|
61
|
+
- MUST use createOrganizationScopedKey() for organization data
|
|
62
|
+
- MUST validate input parameters
|
|
63
|
+
|
|
64
|
+
### Key Format
|
|
65
|
+
- MUST use `:` as separator
|
|
66
|
+
- MUST follow pattern: `scope:identifier:section`
|
|
67
|
+
- MUST include all three parts
|
|
68
|
+
- MUST be descriptive and searchable
|
|
69
|
+
- MUST be consistent across codebase
|
|
70
|
+
|
|
71
|
+
### Type Safety
|
|
72
|
+
- MUST use generic type parameter for section names
|
|
73
|
+
- MUST provide type inference
|
|
74
|
+
- MUST enforce valid section names
|
|
75
|
+
- MUST support template literal types
|
|
76
|
+
- MUST prevent invalid combinations
|
|
77
|
+
|
|
78
|
+
### Key Usage
|
|
79
|
+
- MUST use with storage repository methods
|
|
80
|
+
- MUST maintain type safety through usage chain
|
|
81
|
+
- MUST support pattern-based operations
|
|
82
|
+
- MUST enable efficient key lookup
|
|
83
|
+
|
|
84
|
+
### Key Serialization
|
|
85
|
+
- MUST convert to string for storage operations
|
|
86
|
+
- MUST preserve structure information
|
|
87
|
+
- MUST support reverse transformation
|
|
88
|
+
- MUST handle special characters correctly
|
|
89
|
+
|
|
90
|
+
### Pattern Matching
|
|
91
|
+
- MUST support wildcard patterns for invalidation
|
|
92
|
+
- MUST use consistent separator in patterns
|
|
93
|
+
- MUST enable bulk operations
|
|
94
|
+
- MUST handle pattern edge cases
|
|
95
|
+
|
|
96
|
+
### Type Guards
|
|
97
|
+
- MUST provide isUserKey() guard
|
|
98
|
+
- MUST provide isAppKey() guard
|
|
99
|
+
- MUST provide isOrgKey() guard
|
|
100
|
+
- MUST use predicate return types
|
|
101
|
+
- MUST validate key structure
|
|
102
|
+
|
|
103
|
+
### Error Handling
|
|
104
|
+
- MUST validate key format
|
|
105
|
+
- MUST throw descriptive errors for invalid keys
|
|
106
|
+
- MUST include key in error context
|
|
107
|
+
- MUST handle edge cases gracefully
|
|
108
|
+
|
|
109
|
+
### Documentation
|
|
110
|
+
- MUST document key patterns
|
|
111
|
+
- MUST specify format for each scope
|
|
112
|
+
- MUST provide examples in comments
|
|
113
|
+
- MUST warn about common mistakes
|
|
114
|
+
|
|
115
|
+
### Testing Requirements
|
|
116
|
+
- MUST test key creation with valid inputs
|
|
117
|
+
- MUST test key validation with invalid inputs
|
|
118
|
+
- MUST test type guard behavior
|
|
119
|
+
- MUST test pattern matching
|
|
120
|
+
- MUST test serialization
|
package/src/index.ts
CHANGED
|
File without changes
|
|
@@ -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,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
|