@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.
- package/package.json +5 -6
- package/src/device/infrastructure/repositories/LegacyDeviceIdRepository.ts +1 -1
- package/src/device/infrastructure/services/DeviceFeatureService.ts +1 -1
- package/src/exception/infrastructure/services/ExceptionLogger.ts +1 -1
- package/src/exception/infrastructure/storage/ExceptionStore.ts +1 -1
- package/src/exports/filesystem.ts +1 -0
- package/src/exports/storage.ts +1 -0
- package/src/filesystem/domain/constants/FileConstants.ts +20 -0
- package/src/filesystem/domain/entities/File.ts +20 -0
- package/src/filesystem/domain/types/FileTypes.ts +43 -0
- package/src/filesystem/domain/utils/FileUtils.ts +86 -0
- package/src/filesystem/index.ts +23 -0
- package/src/filesystem/infrastructure/services/FileSystemService.ts +45 -0
- package/src/filesystem/infrastructure/services/cache.service.ts +48 -0
- package/src/filesystem/infrastructure/services/directory.service.ts +66 -0
- package/src/filesystem/infrastructure/services/download.constants.ts +6 -0
- package/src/filesystem/infrastructure/services/download.service.ts +74 -0
- package/src/filesystem/infrastructure/services/download.types.ts +7 -0
- package/src/filesystem/infrastructure/services/encoding.service.ts +25 -0
- package/src/filesystem/infrastructure/services/file-info.service.ts +52 -0
- package/src/filesystem/infrastructure/services/file-manager.service.ts +81 -0
- package/src/filesystem/infrastructure/services/file-path.service.ts +22 -0
- package/src/filesystem/infrastructure/services/file-reader.service.ts +52 -0
- package/src/filesystem/infrastructure/services/file-writer.service.ts +32 -0
- package/src/filesystem/infrastructure/utils/blob.utils.ts +20 -0
- package/src/image/infrastructure/services/ImageStorageService.ts +1 -1
- package/src/index.ts +9 -0
- package/src/molecules/alerts/AlertStore.ts +1 -1
- package/src/molecules/calendar/infrastructure/storage/EventActions.ts +1 -1
- package/src/molecules/calendar/infrastructure/stores/storageAdapter.ts +1 -1
- package/src/offline/infrastructure/storage/OfflineStore.ts +1 -1
- package/src/onboarding/infrastructure/storage/OnboardingStore.ts +2 -2
- package/src/onboarding/infrastructure/storage/__tests__/OnboardingStore.test.ts +1 -1
- package/src/onboarding/infrastructure/storage/actions/answerActions.ts +1 -1
- package/src/onboarding/infrastructure/storage/actions/storageHelpers.ts +1 -1
- package/src/storage/README.md +185 -0
- package/src/storage/__tests__/integration.test.ts +391 -0
- package/src/storage/__tests__/mocks/asyncStorage.mock.ts +52 -0
- package/src/storage/__tests__/performance.test.tsx +352 -0
- package/src/storage/__tests__/setup.ts +63 -0
- package/src/storage/application/README.md +158 -0
- package/src/storage/application/ports/IStorageRepository.ts +61 -0
- package/src/storage/application/ports/README.md +127 -0
- package/src/storage/cache/README.md +154 -0
- package/src/storage/cache/__tests__/PerformanceAndMemory.test.ts +387 -0
- package/src/storage/cache/__tests__/setup.ts +19 -0
- package/src/storage/cache/domain/Cache.ts +146 -0
- package/src/storage/cache/domain/CacheManager.md +83 -0
- package/src/storage/cache/domain/CacheManager.ts +48 -0
- package/src/storage/cache/domain/CacheStatsTracker.md +169 -0
- package/src/storage/cache/domain/CacheStatsTracker.ts +49 -0
- package/src/storage/cache/domain/CachedValue.md +97 -0
- package/src/storage/cache/domain/ErrorHandler.md +99 -0
- package/src/storage/cache/domain/ErrorHandler.ts +42 -0
- package/src/storage/cache/domain/PatternMatcher.md +122 -0
- package/src/storage/cache/domain/PatternMatcher.ts +30 -0
- package/src/storage/cache/domain/README.md +118 -0
- package/src/storage/cache/domain/__tests__/Cache.test.ts +293 -0
- package/src/storage/cache/domain/__tests__/CacheManager.test.ts +276 -0
- package/src/storage/cache/domain/__tests__/ErrorHandler.test.ts +303 -0
- package/src/storage/cache/domain/__tests__/PatternMatcher.test.ts +261 -0
- package/src/storage/cache/domain/strategies/EvictionStrategy.ts +9 -0
- package/src/storage/cache/domain/strategies/FIFOStrategy.ts +12 -0
- package/src/storage/cache/domain/strategies/LFUStrategy.ts +22 -0
- package/src/storage/cache/domain/strategies/LRUStrategy.ts +22 -0
- package/src/storage/cache/domain/strategies/README.md +117 -0
- package/src/storage/cache/domain/strategies/TTLStrategy.ts +23 -0
- package/src/storage/cache/domain/strategies/__tests__/EvictionStrategies.test.ts +293 -0
- package/src/storage/cache/domain/types/Cache.ts +28 -0
- package/src/storage/cache/domain/types/README.md +107 -0
- package/src/storage/cache/index.ts +28 -0
- package/src/storage/cache/infrastructure/README.md +126 -0
- package/src/storage/cache/infrastructure/TTLCache.ts +103 -0
- package/src/storage/cache/infrastructure/__tests__/TTLCache.test.ts +303 -0
- package/src/storage/cache/presentation/README.md +123 -0
- package/src/storage/cache/presentation/__tests__/ReactHooks.test.ts +514 -0
- package/src/storage/cache/presentation/useCache.ts +76 -0
- package/src/storage/cache/presentation/useCachedValue.ts +88 -0
- package/src/storage/cache/types.d.ts +3 -0
- package/src/storage/domain/README.md +128 -0
- package/src/storage/domain/constants/CacheDefaults.ts +64 -0
- package/src/storage/domain/constants/README.md +105 -0
- package/src/storage/domain/entities/CachedValue.ts +86 -0
- package/src/storage/domain/entities/README.md +109 -0
- package/src/storage/domain/entities/StorageResult.ts +75 -0
- package/src/storage/domain/entities/__tests__/CachedValue.test.ts +149 -0
- package/src/storage/domain/entities/__tests__/StorageResult.test.ts +122 -0
- package/src/storage/domain/errors/README.md +126 -0
- package/src/storage/domain/errors/StorageError.ts +81 -0
- package/src/storage/domain/errors/__tests__/StorageError.test.ts +127 -0
- package/src/storage/domain/factories/README.md +138 -0
- package/src/storage/domain/factories/StoreFactory.ts +59 -0
- package/src/storage/domain/types/README.md +522 -0
- package/src/storage/domain/types/Store.ts +44 -0
- package/src/storage/domain/utils/CacheKeyGenerator.ts +66 -0
- package/src/storage/domain/utils/README.md +127 -0
- package/src/storage/domain/utils/__tests__/devUtils.test.ts +97 -0
- package/src/storage/domain/utils/devUtils.ts +37 -0
- package/src/storage/domain/value-objects/README.md +120 -0
- package/src/storage/domain/value-objects/StorageKey.ts +60 -0
- package/src/storage/index.ts +175 -0
- package/src/storage/infrastructure/README.md +165 -0
- package/src/storage/infrastructure/adapters/README.md +175 -0
- package/src/storage/infrastructure/adapters/StorageService.md +103 -0
- package/src/storage/infrastructure/adapters/StorageService.ts +49 -0
- package/src/storage/infrastructure/repositories/AsyncStorageRepository.ts +98 -0
- package/src/storage/infrastructure/repositories/BaseStorageOperations.ts +100 -0
- package/src/storage/infrastructure/repositories/BatchStorageOperations.ts +42 -0
- package/src/storage/infrastructure/repositories/README.md +121 -0
- package/src/storage/infrastructure/repositories/StringStorageOperations.ts +44 -0
- package/src/storage/infrastructure/repositories/__tests__/AsyncStorageRepository.test.ts +170 -0
- package/src/storage/infrastructure/repositories/__tests__/BaseStorageOperations.test.ts +201 -0
- package/src/storage/presentation/README.md +181 -0
- package/src/storage/presentation/hooks/CacheStorageOperations.ts +94 -0
- package/src/storage/presentation/hooks/README.md +128 -0
- package/src/storage/presentation/hooks/__tests__/usePersistentCache.test.ts +405 -0
- package/src/storage/presentation/hooks/__tests__/useStorage.test.ts +247 -0
- package/src/storage/presentation/hooks/__tests__/useStorageState.test.ts +293 -0
- package/src/storage/presentation/hooks/useCacheState.ts +53 -0
- package/src/storage/presentation/hooks/usePersistentCache.ts +154 -0
- package/src/storage/presentation/hooks/useStorage.ts +102 -0
- package/src/storage/presentation/hooks/useStorageState.ts +71 -0
- package/src/storage/presentation/hooks/useStore.ts +15 -0
- package/src/storage/types/README.md +103 -0
- package/src/theme/infrastructure/globalThemeStore.ts +1 -1
- package/src/theme/infrastructure/storage/ThemeStorage.ts +1 -1
- package/src/theme/infrastructure/stores/themeStore.ts +1 -1
- package/src/utilities/sharing/infrastructure/services/SharingService.ts +1 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Domain Layer
|
|
2
|
+
|
|
3
|
+
Core business logic, entities, value objects, and error handling for storage operations.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The domain layer contains the fundamental business logic and types used throughout the storage system. Located at `src/domain/`.
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
domain/
|
|
13
|
+
├── constants/ # Time constants and defaults
|
|
14
|
+
├── entities/ # Domain entities (CachedValue, Result)
|
|
15
|
+
├── errors/ # Error classes and types
|
|
16
|
+
├── factories/ # Zustand store factory
|
|
17
|
+
├── types/ # TypeScript type definitions
|
|
18
|
+
├── utils/ # Helper functions
|
|
19
|
+
└── value-objects/ # StorageKey value objects
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Strategies
|
|
23
|
+
|
|
24
|
+
### Value Objects
|
|
25
|
+
- Use StorageKey for type-safe storage keys
|
|
26
|
+
- Create scoped keys (user, organization, app)
|
|
27
|
+
- Use key factories for consistent key generation
|
|
28
|
+
- Document key structure patterns
|
|
29
|
+
|
|
30
|
+
### Error Handling
|
|
31
|
+
- Use specific error types for different failure scenarios
|
|
32
|
+
- Apply Result pattern for type-safe error handling
|
|
33
|
+
- Preserve error context (key, operation, cause)
|
|
34
|
+
- Categorize errors by type (read, write, serialization)
|
|
35
|
+
|
|
36
|
+
### Store Factory
|
|
37
|
+
- Use createStore for Zustand store creation
|
|
38
|
+
- Implement persist for state persistence
|
|
39
|
+
- Use versioning and migration for schema changes
|
|
40
|
+
- Apply partialize to select persisted state
|
|
41
|
+
|
|
42
|
+
### Key Generation
|
|
43
|
+
- Use generateCacheKey for cache entries
|
|
44
|
+
- Use generateListCacheKey for list queries
|
|
45
|
+
- Document key patterns in code comments
|
|
46
|
+
- Use parseCacheKey for key extraction
|
|
47
|
+
|
|
48
|
+
## Restrictions
|
|
49
|
+
|
|
50
|
+
### Value Objects
|
|
51
|
+
- DO NOT create keys without using factory functions
|
|
52
|
+
- DO NOT mix key scopes (user vs app vs org)
|
|
53
|
+
- DO NOT use dynamic strings as storage keys
|
|
54
|
+
- DO NOT create ambiguous key structures
|
|
55
|
+
|
|
56
|
+
### Error Handling
|
|
57
|
+
- DO NOT throw exceptions from Result types
|
|
58
|
+
- DO NOT use generic Error class
|
|
59
|
+
- DO NOT lose error context when wrapping errors
|
|
60
|
+
- DO NOT ignore error states in Result objects
|
|
61
|
+
|
|
62
|
+
### Store Factory
|
|
63
|
+
- DO NOT create stores without names
|
|
64
|
+
- DO NOT use persist without version number
|
|
65
|
+
- DO NOT change schema without migration
|
|
66
|
+
- DO NOT persist sensitive data without encryption
|
|
67
|
+
|
|
68
|
+
### Type Safety
|
|
69
|
+
- DO NOT use `any` for type parameters
|
|
70
|
+
- DO NOT skip type guards for runtime validation
|
|
71
|
+
- DO NOT assume Result is always success
|
|
72
|
+
- DO NOT cast values without validation
|
|
73
|
+
|
|
74
|
+
## Rules
|
|
75
|
+
|
|
76
|
+
### Value Objects (StorageKey)
|
|
77
|
+
- MUST use factory functions for key creation
|
|
78
|
+
- MUST use consistent key structure (prefix:params)
|
|
79
|
+
- MUST include scope prefix (app:, user:, org:)
|
|
80
|
+
- MUST document key patterns
|
|
81
|
+
|
|
82
|
+
### Error Classes
|
|
83
|
+
- MUST extend StorageError base class
|
|
84
|
+
- MUST include error code
|
|
85
|
+
- MUST preserve error context (key, operation)
|
|
86
|
+
- MUST attach cause error when wrapping exceptions
|
|
87
|
+
|
|
88
|
+
### Result Pattern
|
|
89
|
+
- MUST use success() for successful operations
|
|
90
|
+
- MUST use failure() for errors
|
|
91
|
+
- MUST check success flag before accessing data
|
|
92
|
+
- MUST provide type parameter for data
|
|
93
|
+
|
|
94
|
+
### Store Factory
|
|
95
|
+
- MUST provide unique store name
|
|
96
|
+
- MUST define initial state
|
|
97
|
+
- MUST specify version when persist is enabled
|
|
98
|
+
- MUST implement migrate function for schema changes
|
|
99
|
+
|
|
100
|
+
### Type Definitions
|
|
101
|
+
- MUST use generic type parameters
|
|
102
|
+
- MUST provide type inference
|
|
103
|
+
- MUST enforce type safety
|
|
104
|
+
- MUST document complex types
|
|
105
|
+
|
|
106
|
+
### Constants
|
|
107
|
+
- MUST use TIME_MS for time values
|
|
108
|
+
- MUST use DEFAULT_TTL for cache TTL
|
|
109
|
+
- MUST define constants in separate files
|
|
110
|
+
- MUST export constants for external use
|
|
111
|
+
|
|
112
|
+
### Utilities
|
|
113
|
+
- MUST validate input parameters
|
|
114
|
+
- MUST handle edge cases gracefully
|
|
115
|
+
- MUST provide type guards for validation
|
|
116
|
+
- MUST log warnings in development
|
|
117
|
+
|
|
118
|
+
### Testing
|
|
119
|
+
- MUST test error scenarios
|
|
120
|
+
- MUST test Result pattern operations
|
|
121
|
+
- MUST validate key generation
|
|
122
|
+
- MUST test store creation and persistence
|
|
123
|
+
|
|
124
|
+
### Documentation
|
|
125
|
+
- MUST document complex types
|
|
126
|
+
- MUST specify error codes
|
|
127
|
+
- MUST provide usage examples in comments
|
|
128
|
+
- MUST warn about common mistakes
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache Default Constants
|
|
3
|
+
* Domain layer - Default values for caching
|
|
4
|
+
*
|
|
5
|
+
* General-purpose constants for any app
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Time constants in milliseconds
|
|
10
|
+
*/
|
|
11
|
+
export const TIME_MS = {
|
|
12
|
+
SECOND: 1000,
|
|
13
|
+
MINUTE: 60 * 1000,
|
|
14
|
+
HOUR: 60 * 60 * 1000,
|
|
15
|
+
DAY: 24 * 60 * 60 * 1000,
|
|
16
|
+
WEEK: 7 * 24 * 60 * 60 * 1000,
|
|
17
|
+
} as const;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Default TTL values for different cache types
|
|
21
|
+
*/
|
|
22
|
+
export const DEFAULT_TTL = {
|
|
23
|
+
/**
|
|
24
|
+
* Very short cache (1 minute)
|
|
25
|
+
* Use for: Real-time data, live updates
|
|
26
|
+
*/
|
|
27
|
+
VERY_SHORT: TIME_MS.MINUTE,
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Short cache (5 minutes)
|
|
31
|
+
* Use for: Frequently changing data
|
|
32
|
+
*/
|
|
33
|
+
SHORT: 5 * TIME_MS.MINUTE,
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Medium cache (30 minutes)
|
|
37
|
+
* Use for: Moderately changing data, user-specific content
|
|
38
|
+
*/
|
|
39
|
+
MEDIUM: 30 * TIME_MS.MINUTE,
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Long cache (2 hours)
|
|
43
|
+
* Use for: Slowly changing data, public content
|
|
44
|
+
*/
|
|
45
|
+
LONG: 2 * TIME_MS.HOUR,
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Very long cache (24 hours)
|
|
49
|
+
* Use for: Rarely changing data, master data
|
|
50
|
+
*/
|
|
51
|
+
VERY_LONG: TIME_MS.DAY,
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Permanent cache (7 days)
|
|
55
|
+
* Use for: Static content, app configuration
|
|
56
|
+
*/
|
|
57
|
+
PERMANENT: TIME_MS.WEEK,
|
|
58
|
+
} as const;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Cache version for global invalidation
|
|
62
|
+
* Increment this to invalidate all caches across the app
|
|
63
|
+
*/
|
|
64
|
+
export const CACHE_VERSION = 1;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Domain Constants
|
|
2
|
+
|
|
3
|
+
Time constants and default values for storage and cache operations.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Constant values for time-based calculations and default configuration. Located at `src/domain/constants/`.
|
|
8
|
+
|
|
9
|
+
## Strategies
|
|
10
|
+
|
|
11
|
+
### Time Constants
|
|
12
|
+
- Use TIME_MS for all time-based calculations
|
|
13
|
+
- Provide constants for common time units
|
|
14
|
+
- Enable readable time calculations
|
|
15
|
+
- Support time arithmetic
|
|
16
|
+
|
|
17
|
+
### Default Values
|
|
18
|
+
- Use DEFAULT_TTL for standard cache lifetime
|
|
19
|
+
- Set sensible defaults for common use cases
|
|
20
|
+
- Document default value rationale
|
|
21
|
+
- Allow override for specific needs
|
|
22
|
+
|
|
23
|
+
### Version Management
|
|
24
|
+
- Use CACHE_VERSION for cache key versioning
|
|
25
|
+
- Increment version on breaking changes
|
|
26
|
+
- Support migration between versions
|
|
27
|
+
- Include version in cache keys
|
|
28
|
+
|
|
29
|
+
## Restrictions
|
|
30
|
+
|
|
31
|
+
### Time Calculations
|
|
32
|
+
- DO NOT use hardcoded millisecond values
|
|
33
|
+
- DO NOT calculate time values inline
|
|
34
|
+
- DO NOT mix time units (seconds vs milliseconds)
|
|
35
|
+
- DO NOT use magic numbers for time
|
|
36
|
+
|
|
37
|
+
### Constants
|
|
38
|
+
- DO NOT redefine TIME_MS values elsewhere
|
|
39
|
+
- DO NOT modify constants at runtime
|
|
40
|
+
- DO NOT use deprecated constants
|
|
41
|
+
- DO NOT create duplicate constants
|
|
42
|
+
|
|
43
|
+
### Version Management
|
|
44
|
+
- DO NOT skip version numbers
|
|
45
|
+
- DO NOT reuse old versions
|
|
46
|
+
- DO NOT forget to update CACHE_VERSION
|
|
47
|
+
- DO NOT change version format
|
|
48
|
+
|
|
49
|
+
## Rules
|
|
50
|
+
|
|
51
|
+
### TIME_MS Constants
|
|
52
|
+
- MUST provide SECOND (1000ms)
|
|
53
|
+
- MUST provide MINUTE (60000ms)
|
|
54
|
+
- MUST provide HOUR (3600000ms)
|
|
55
|
+
- MUST provide DAY (86400000ms)
|
|
56
|
+
- MUST provide WEEK (604800000ms)
|
|
57
|
+
- MUST be in milliseconds
|
|
58
|
+
|
|
59
|
+
### DEFAULT_TTL
|
|
60
|
+
- MUST be set to 300000 (5 minutes)
|
|
61
|
+
- MUST be used for cache when no TTL specified
|
|
62
|
+
- MUST balance freshness and performance
|
|
63
|
+
- MUST be documented
|
|
64
|
+
|
|
65
|
+
### CACHE_VERSION
|
|
66
|
+
- MUST be integer value
|
|
67
|
+
- MUST start at 1
|
|
68
|
+
- MUST increment on breaking changes
|
|
69
|
+
- MUST be included in cache keys
|
|
70
|
+
|
|
71
|
+
### Constant Usage
|
|
72
|
+
- MUST use TIME_MS for all time calculations
|
|
73
|
+
- MUST use DEFAULT_TTL for default cache lifetime
|
|
74
|
+
- MUST use CACHE_VERSION for versioning
|
|
75
|
+
- MUST not calculate values inline
|
|
76
|
+
|
|
77
|
+
### Time Arithmetic
|
|
78
|
+
- MUST use TIME_MS constants for calculations
|
|
79
|
+
- MUST support multiplication for extended periods
|
|
80
|
+
- MUST be readable and maintainable
|
|
81
|
+
- MUST avoid magic numbers
|
|
82
|
+
|
|
83
|
+
### Version Control
|
|
84
|
+
- MUST increment CACHE_VERSION on schema changes
|
|
85
|
+
- MUST implement migration for old versions
|
|
86
|
+
- MUST document breaking changes
|
|
87
|
+
- MUST support backward compatibility where possible
|
|
88
|
+
|
|
89
|
+
### Export Rules
|
|
90
|
+
- MUST export all constants
|
|
91
|
+
- MUST use const for immutability
|
|
92
|
+
- MUST organize constants by purpose
|
|
93
|
+
- MUST provide TypeScript types
|
|
94
|
+
|
|
95
|
+
### Documentation
|
|
96
|
+
- MUST document time units clearly
|
|
97
|
+
- MUST specify values in milliseconds
|
|
98
|
+
- MUST explain default value choices
|
|
99
|
+
- MUST warn about common mistakes
|
|
100
|
+
|
|
101
|
+
### Testing Requirements
|
|
102
|
+
- MUST test time constant values
|
|
103
|
+
- MUST verify version increment logic
|
|
104
|
+
- MUST test migration between versions
|
|
105
|
+
- MUST validate default TTL usage
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cached Value Entity
|
|
3
|
+
* Domain layer - Represents a cached value with TTL metadata
|
|
4
|
+
*
|
|
5
|
+
* General-purpose cache entity for any app that needs persistent caching
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Cached value with time-to-live metadata
|
|
10
|
+
* Generic type T can be any serializable data
|
|
11
|
+
*/
|
|
12
|
+
export interface CachedValue<T> {
|
|
13
|
+
/**
|
|
14
|
+
* The actual cached data
|
|
15
|
+
*/
|
|
16
|
+
value: T;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Timestamp when the value was cached (milliseconds)
|
|
20
|
+
*/
|
|
21
|
+
cachedAt: number;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Timestamp when the cache expires (milliseconds)
|
|
25
|
+
*/
|
|
26
|
+
expiresAt: number;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Optional version for cache invalidation
|
|
30
|
+
* Increment version to invalidate all caches
|
|
31
|
+
*/
|
|
32
|
+
version?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Create a new cached value with TTL
|
|
37
|
+
* @param value - Data to cache
|
|
38
|
+
* @param ttlMs - Time-to-live in milliseconds
|
|
39
|
+
* @param version - Optional version number
|
|
40
|
+
*/
|
|
41
|
+
export function createCachedValue<T>(
|
|
42
|
+
value: T,
|
|
43
|
+
ttlMs: number,
|
|
44
|
+
version?: number,
|
|
45
|
+
): CachedValue<T> {
|
|
46
|
+
const now = Date.now();
|
|
47
|
+
return {
|
|
48
|
+
value,
|
|
49
|
+
cachedAt: now,
|
|
50
|
+
expiresAt: now + ttlMs,
|
|
51
|
+
version,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check if cached value is expired
|
|
57
|
+
* @param cached - Cached value to check
|
|
58
|
+
* @param currentVersion - Optional current version to check against
|
|
59
|
+
*/
|
|
60
|
+
export function isCacheExpired<T>(
|
|
61
|
+
cached: CachedValue<T>,
|
|
62
|
+
currentVersion?: number,
|
|
63
|
+
): boolean {
|
|
64
|
+
const now = Date.now();
|
|
65
|
+
const timeExpired = now > cached.expiresAt;
|
|
66
|
+
const versionMismatch = currentVersion !== undefined && cached.version !== currentVersion;
|
|
67
|
+
return timeExpired || versionMismatch;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get remaining TTL in milliseconds
|
|
72
|
+
* Returns 0 if expired
|
|
73
|
+
*/
|
|
74
|
+
export function getRemainingTTL<T>(cached: CachedValue<T>): number {
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
const remaining = cached.expiresAt - now;
|
|
77
|
+
return Math.max(0, remaining);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get cache age in milliseconds
|
|
82
|
+
*/
|
|
83
|
+
export function getCacheAge<T>(cached: CachedValue<T>): number {
|
|
84
|
+
const now = Date.now();
|
|
85
|
+
return now - cached.cachedAt;
|
|
86
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Domain Entities
|
|
2
|
+
|
|
3
|
+
Core entities for the storage domain including CachedValue and Result pattern.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Fundamental domain entities used throughout the storage system. Located at `src/domain/entities/`.
|
|
8
|
+
|
|
9
|
+
## Strategies
|
|
10
|
+
|
|
11
|
+
### CachedValue Entity
|
|
12
|
+
- Use for cache entries with TTL and metadata
|
|
13
|
+
- Track creation timestamp for expiration
|
|
14
|
+
- Support TTL-based expiration checking
|
|
15
|
+
- Enable age calculation and remaining TTL queries
|
|
16
|
+
|
|
17
|
+
### Result Pattern
|
|
18
|
+
- Use discriminated union for type-safe error handling
|
|
19
|
+
- Provide success/failure states with type narrowing
|
|
20
|
+
- Include error context in failure state
|
|
21
|
+
- Support functional transformations (map, unwrap)
|
|
22
|
+
|
|
23
|
+
### Entity Composition
|
|
24
|
+
- Combine CachedValue with cache operations
|
|
25
|
+
- Use Result for all storage operations
|
|
26
|
+
- Enable error propagation without exceptions
|
|
27
|
+
- Support functional error handling patterns
|
|
28
|
+
|
|
29
|
+
## Restrictions
|
|
30
|
+
|
|
31
|
+
### CachedValue
|
|
32
|
+
- DO NOT modify timestamp after creation (except for sliding expiration)
|
|
33
|
+
- DO NOT adjust TTL manually to extend lifetime
|
|
34
|
+
- DO NOT create CachedValue without factory function
|
|
35
|
+
- DO NOT use negative or zero TTL values
|
|
36
|
+
|
|
37
|
+
### Result Pattern
|
|
38
|
+
- DO NOT throw exceptions from Result operations
|
|
39
|
+
- DO NOT access data without checking success flag
|
|
40
|
+
- DO NOT ignore failure states
|
|
41
|
+
- DO NOT mix success and failure in same type
|
|
42
|
+
|
|
43
|
+
### Type Safety
|
|
44
|
+
- DO NOT use `any` for Result data type
|
|
45
|
+
- DO NOT skip type guards when checking results
|
|
46
|
+
- DO NOT cast results without validation
|
|
47
|
+
- DO NOT create circular type dependencies
|
|
48
|
+
|
|
49
|
+
## Rules
|
|
50
|
+
|
|
51
|
+
### CachedValue Entity
|
|
52
|
+
- MUST use generic type parameter <T> for data
|
|
53
|
+
- MUST include timestamp (milliseconds since epoch)
|
|
54
|
+
- MUST include ttl (time to live in milliseconds)
|
|
55
|
+
- MUST provide factory function for creation
|
|
56
|
+
- MUST validate structure on creation
|
|
57
|
+
|
|
58
|
+
### Result Type
|
|
59
|
+
- MUST use discriminated union with success flag
|
|
60
|
+
- MUST include data in success state
|
|
61
|
+
- MUST include error in failure state
|
|
62
|
+
- MUST provide type parameter for data type
|
|
63
|
+
- MUST enable type narrowing with success flag
|
|
64
|
+
|
|
65
|
+
### Factory Functions
|
|
66
|
+
- MUST provide createCachedValue(data, ttl)
|
|
67
|
+
- MUST provide success(data) factory
|
|
68
|
+
- MUST provide failure(error) factory
|
|
69
|
+
- MUST validate input parameters
|
|
70
|
+
- MUST return properly typed entities
|
|
71
|
+
|
|
72
|
+
### Type Guards
|
|
73
|
+
- MUST provide isSuccess() type guard
|
|
74
|
+
- MUST provide isFailure() type guard
|
|
75
|
+
- MUST provide isCacheExpired() validator
|
|
76
|
+
- MUST use predicate return type for type narrowing
|
|
77
|
+
- MUST validate all required fields
|
|
78
|
+
|
|
79
|
+
### Utility Functions
|
|
80
|
+
- MUST provide getRemainingTTL() for cache entries
|
|
81
|
+
- MUST provide getCacheAge() for cache entries
|
|
82
|
+
- MUST provide unwrap() for Result extraction
|
|
83
|
+
- MUST provide map() for Result transformation
|
|
84
|
+
- MUST handle edge cases (null, undefined)
|
|
85
|
+
|
|
86
|
+
### Error Handling
|
|
87
|
+
- MUST preserve error context in failures
|
|
88
|
+
- MUST attach cause errors when wrapping
|
|
89
|
+
- MUST include error codes for categorization
|
|
90
|
+
- MUST log errors in development mode
|
|
91
|
+
|
|
92
|
+
### Serialization
|
|
93
|
+
- MUST support JSON serialization for CachedValue
|
|
94
|
+
- MUST validate structure after deserialization
|
|
95
|
+
- MUST handle circular reference errors
|
|
96
|
+
- MUST provide type guards for validation
|
|
97
|
+
|
|
98
|
+
### Testing Requirements
|
|
99
|
+
- MUST test entity creation and validation
|
|
100
|
+
- MUST test expiration logic with various TTL values
|
|
101
|
+
- MUST test Result pattern operations
|
|
102
|
+
- MUST test type guard behavior
|
|
103
|
+
- MUST test edge cases
|
|
104
|
+
|
|
105
|
+
### Documentation
|
|
106
|
+
- MUST document all public methods
|
|
107
|
+
- MUST specify parameter types and return types
|
|
108
|
+
- MUST provide usage guidance without code examples
|
|
109
|
+
- MUST warn about common mistakes
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage Result Entity
|
|
3
|
+
*
|
|
4
|
+
* Domain-Driven Design: Entity representing storage operation result
|
|
5
|
+
* Functional programming pattern for error handling (Result type)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { StorageError } from '../errors/StorageError';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Storage Operation Result
|
|
12
|
+
* Success/Failure pattern for type-safe error handling
|
|
13
|
+
*/
|
|
14
|
+
export type StorageResult<T> =
|
|
15
|
+
| { success: true; data: T }
|
|
16
|
+
| { success: false; error: StorageError; fallback?: T };
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create success result
|
|
20
|
+
*/
|
|
21
|
+
export const success = <T>(data: T): StorageResult<T> => ({
|
|
22
|
+
success: true,
|
|
23
|
+
data,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Create failure result
|
|
28
|
+
*/
|
|
29
|
+
export const failure = <T>(error: StorageError, fallback?: T): StorageResult<T> => ({
|
|
30
|
+
success: false,
|
|
31
|
+
error,
|
|
32
|
+
fallback,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Type guard for success result
|
|
37
|
+
*/
|
|
38
|
+
export const isSuccess = <T>(result: StorageResult<T>): result is { success: true; data: T } => {
|
|
39
|
+
return result.success === true;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Type guard for failure result
|
|
44
|
+
*/
|
|
45
|
+
export const isFailure = <T>(result: StorageResult<T>): result is { success: false; error: StorageError; fallback?: T } => {
|
|
46
|
+
return result.success === false;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Unwrap result with default value
|
|
51
|
+
*/
|
|
52
|
+
export const unwrap = <T>(result: StorageResult<T>, defaultValue: T): T => {
|
|
53
|
+
if (isSuccess(result)) {
|
|
54
|
+
return result.data;
|
|
55
|
+
}
|
|
56
|
+
// Type guard ensures we can access fallback
|
|
57
|
+
if (isFailure(result) && result.fallback !== undefined) {
|
|
58
|
+
return result.fallback;
|
|
59
|
+
}
|
|
60
|
+
return defaultValue;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Map result data
|
|
65
|
+
*/
|
|
66
|
+
export const map = <T, U>(
|
|
67
|
+
result: StorageResult<T>,
|
|
68
|
+
fn: (data: T) => U
|
|
69
|
+
): StorageResult<U> => {
|
|
70
|
+
if (isSuccess(result)) {
|
|
71
|
+
return success(fn(result.data));
|
|
72
|
+
}
|
|
73
|
+
// For failure, we can't convert fallback type T to U, so we omit it
|
|
74
|
+
return failure(result.error);
|
|
75
|
+
};
|