@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,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Store Types
|
|
3
|
+
* Zustand store configuration with actions support
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { StoreApi } from 'zustand';
|
|
7
|
+
|
|
8
|
+
/** Set function type for Zustand */
|
|
9
|
+
export type SetState<T> = StoreApi<T>['setState'];
|
|
10
|
+
|
|
11
|
+
/** Get function type for Zustand */
|
|
12
|
+
export type GetState<T> = StoreApi<T>['getState'];
|
|
13
|
+
|
|
14
|
+
/** Actions creator function */
|
|
15
|
+
export type ActionsCreator<TState, TActions> = (
|
|
16
|
+
set: SetState<TState & TActions>,
|
|
17
|
+
get: GetState<TState & TActions>
|
|
18
|
+
) => TActions;
|
|
19
|
+
|
|
20
|
+
/** Store configuration */
|
|
21
|
+
export interface StoreConfig<TState extends object, TActions extends object = object> {
|
|
22
|
+
/** Unique store name (used as storage key) */
|
|
23
|
+
name: string;
|
|
24
|
+
/** Initial state */
|
|
25
|
+
initialState: TState;
|
|
26
|
+
/** Actions creator function */
|
|
27
|
+
actions?: ActionsCreator<TState, TActions>;
|
|
28
|
+
/** Enable AsyncStorage persistence */
|
|
29
|
+
persist?: boolean;
|
|
30
|
+
/** State version for migrations */
|
|
31
|
+
version?: number;
|
|
32
|
+
/** Select which state to persist */
|
|
33
|
+
partialize?: (state: TState & TActions) => Partial<TState>;
|
|
34
|
+
/** Callback after rehydration */
|
|
35
|
+
onRehydrate?: (state: TState & TActions) => void;
|
|
36
|
+
/** Migration function for version changes */
|
|
37
|
+
migrate?: (persistedState: unknown, version: number) => TState;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Persisted state wrapper */
|
|
41
|
+
export interface PersistedState<T> {
|
|
42
|
+
state: T;
|
|
43
|
+
version: number;
|
|
44
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache Key Generator
|
|
3
|
+
* Domain layer - Utility for generating consistent cache keys
|
|
4
|
+
*
|
|
5
|
+
* General-purpose key generation for any app
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Generate a cache key from prefix and identifier
|
|
10
|
+
* @param prefix - Cache key prefix (e.g., 'posts', 'products', 'user')
|
|
11
|
+
* @param id - Unique identifier
|
|
12
|
+
* @returns Formatted cache key
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* generateCacheKey('posts', '123') // 'cache:posts:123'
|
|
16
|
+
* generateCacheKey('user', 'profile') // 'cache:user:profile'
|
|
17
|
+
*/
|
|
18
|
+
export function generateCacheKey(prefix: string, id: string | number): string {
|
|
19
|
+
return `cache:${prefix}:${id}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generate a cache key for a list/collection
|
|
24
|
+
* @param prefix - Cache key prefix
|
|
25
|
+
* @param params - Optional query parameters
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* generateListCacheKey('posts') // 'cache:posts:list'
|
|
29
|
+
* generateListCacheKey('posts', { page: 1 }) // 'cache:posts:list:page=1'
|
|
30
|
+
*/
|
|
31
|
+
export function generateListCacheKey(
|
|
32
|
+
prefix: string,
|
|
33
|
+
params?: Record<string, string | number>,
|
|
34
|
+
): string {
|
|
35
|
+
const base = `cache:${prefix}:list`;
|
|
36
|
+
if (!params) return base;
|
|
37
|
+
|
|
38
|
+
const paramString = Object.entries(params)
|
|
39
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
40
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
41
|
+
.join(':');
|
|
42
|
+
|
|
43
|
+
return `${base}:${paramString}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Parse a cache key to extract prefix and id
|
|
48
|
+
* @param key - Cache key to parse
|
|
49
|
+
* @returns Object with prefix and id, or null if invalid
|
|
50
|
+
*/
|
|
51
|
+
export function parseCacheKey(key: string): { prefix: string; id: string } | null {
|
|
52
|
+
const parts = key.split(':');
|
|
53
|
+
if (parts.length < 3 || parts[0] !== 'cache') return null;
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
prefix: parts[1] || '',
|
|
57
|
+
id: parts.slice(2).join(':'),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Check if a key is a cache key
|
|
63
|
+
*/
|
|
64
|
+
export function isCacheKey(key: string): boolean {
|
|
65
|
+
return key.startsWith('cache:');
|
|
66
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Domain Utilities
|
|
2
|
+
|
|
3
|
+
Helper functions for cache key generation and development utilities.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Utility functions for cache operations and development-only features. Located at `src/domain/utils/`.
|
|
8
|
+
|
|
9
|
+
## Strategies
|
|
10
|
+
|
|
11
|
+
### Cache Key Generation
|
|
12
|
+
- Use generateCacheKey() for single items
|
|
13
|
+
- Use generateListCacheKey() for collections
|
|
14
|
+
- Include version in cache keys
|
|
15
|
+
- Support key parsing and validation
|
|
16
|
+
|
|
17
|
+
### Key Format
|
|
18
|
+
- Follow consistent format: `cache:type:id:version`
|
|
19
|
+
- For lists: `cache:type:list:params:version`
|
|
20
|
+
- Use colon (`:`) as separator
|
|
21
|
+
- Enable pattern matching
|
|
22
|
+
|
|
23
|
+
### Development Utilities
|
|
24
|
+
- Use isDev() for environment detection
|
|
25
|
+
- Use devWarn/devError/devLog for dev-only logging
|
|
26
|
+
- Provide no-op functions in production
|
|
27
|
+
- Enable debug features without performance cost
|
|
28
|
+
|
|
29
|
+
### Key Validation
|
|
30
|
+
- Use isCacheKey() for validation
|
|
31
|
+
- Use parseCacheKey() for extraction
|
|
32
|
+
- Support type checking
|
|
33
|
+
- Enable safe key operations
|
|
34
|
+
|
|
35
|
+
## Restrictions
|
|
36
|
+
|
|
37
|
+
### Key Generation
|
|
38
|
+
- DO NOT generate keys manually
|
|
39
|
+
- DO NOT mix key formats
|
|
40
|
+
- DO NOT use inconsistent separators
|
|
41
|
+
- DO NOT omit version from keys
|
|
42
|
+
|
|
43
|
+
### Development Utilities
|
|
44
|
+
- DO NOT log in production (use dev functions)
|
|
45
|
+
- DO NOT include debug code in production builds
|
|
46
|
+
- DO NOT bypass isDev() checks
|
|
47
|
+
- DO NOT leave development code in production
|
|
48
|
+
|
|
49
|
+
### Key Parsing
|
|
50
|
+
- DO NOT parse keys with string methods
|
|
51
|
+
- DO NOT assume key format
|
|
52
|
+
- DO NOT skip validation
|
|
53
|
+
- DO NOT ignore parse errors
|
|
54
|
+
|
|
55
|
+
## Rules
|
|
56
|
+
|
|
57
|
+
### Key Generation Functions
|
|
58
|
+
- MUST provide generateCacheKey(type, id)
|
|
59
|
+
- MUST provide generateListCacheKey(type, params)
|
|
60
|
+
- MUST include version in generated keys
|
|
61
|
+
- MUST use consistent separator
|
|
62
|
+
- MUST validate input parameters
|
|
63
|
+
|
|
64
|
+
### Key Format
|
|
65
|
+
- MUST use format: `cache:{type}:{id}:v{version}`
|
|
66
|
+
- MUST use `:` as separator
|
|
67
|
+
- MUST include version prefix `v`
|
|
68
|
+
- MUST be parseable by parseCacheKey()
|
|
69
|
+
- MUST be unique across different entities
|
|
70
|
+
|
|
71
|
+
### Key Parsing
|
|
72
|
+
- MUST provide parseCacheKey() function
|
|
73
|
+
- MUST return structured data (type, id, version, isList)
|
|
74
|
+
- MUST handle invalid keys gracefully
|
|
75
|
+
- MUST return null for invalid format
|
|
76
|
+
- MUST extract parameters for list keys
|
|
77
|
+
|
|
78
|
+
### Key Validation
|
|
79
|
+
- MUST provide isCacheKey() function
|
|
80
|
+
- MUST validate format string
|
|
81
|
+
- MUST check for required parts
|
|
82
|
+
- MUST return boolean result
|
|
83
|
+
- MUST be used before parsing
|
|
84
|
+
|
|
85
|
+
### Development Functions
|
|
86
|
+
- MUST provide isDev() function
|
|
87
|
+
- MUST provide devWarn() for warnings
|
|
88
|
+
- MUST provide devError() for errors
|
|
89
|
+
- MUST provide devLog() for general logging
|
|
90
|
+
- MUST no-op in production
|
|
91
|
+
|
|
92
|
+
### Environment Detection
|
|
93
|
+
- MUST check __DEV__ or equivalent
|
|
94
|
+
- MUST return boolean for isDev()
|
|
95
|
+
- MUST be compile-time constant when possible
|
|
96
|
+
- MUST not have runtime overhead in production
|
|
97
|
+
|
|
98
|
+
### Logging Functions
|
|
99
|
+
- MUST only log in development mode
|
|
100
|
+
- MUST accept variable arguments
|
|
101
|
+
- MUST use console methods appropriately
|
|
102
|
+
- MUST not expose sensitive data
|
|
103
|
+
|
|
104
|
+
### TypeScript Types
|
|
105
|
+
- MUST provide ParsedCacheKey interface
|
|
106
|
+
- MUST specify function signatures
|
|
107
|
+
- MUST enable type inference
|
|
108
|
+
- MUST use generic types where appropriate
|
|
109
|
+
|
|
110
|
+
### Performance
|
|
111
|
+
- MUST not perform expensive operations in dev checks
|
|
112
|
+
- MUST provide no-op implementations in production
|
|
113
|
+
- MUST minimize bundle size impact
|
|
114
|
+
- MUST not include dev tools in production builds
|
|
115
|
+
|
|
116
|
+
### Export Rules
|
|
117
|
+
- MUST export all utility functions
|
|
118
|
+
- MUST organize exports by category
|
|
119
|
+
- MUST provide TypeScript types
|
|
120
|
+
- MUST document function behavior
|
|
121
|
+
|
|
122
|
+
### Testing Requirements
|
|
123
|
+
- MUST test key generation with various inputs
|
|
124
|
+
- MUST test key parsing with valid and invalid keys
|
|
125
|
+
- MUST test validation functions
|
|
126
|
+
- MUST test development mode detection
|
|
127
|
+
- MUST verify production no-op behavior
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Development Utilities Tests
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { isDev, devWarn, devError, devLog } from '../devUtils';
|
|
6
|
+
|
|
7
|
+
// Mock console methods
|
|
8
|
+
const mockConsoleWarn = jest.fn();
|
|
9
|
+
const mockConsoleError = jest.fn();
|
|
10
|
+
const mockConsoleLog = jest.fn();
|
|
11
|
+
|
|
12
|
+
describe('Development Utilities', () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
jest.clearAllMocks();
|
|
15
|
+
|
|
16
|
+
// Mock console methods
|
|
17
|
+
console.warn = mockConsoleWarn;
|
|
18
|
+
console.error = mockConsoleError;
|
|
19
|
+
console.log = mockConsoleLog;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('isDev', () => {
|
|
23
|
+
it('should return true when __DEV__ is true', () => {
|
|
24
|
+
(globalThis as any).__DEV__ = true;
|
|
25
|
+
expect(isDev()).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should return false when __DEV__ is false', () => {
|
|
29
|
+
(globalThis as any).__DEV__ = false;
|
|
30
|
+
expect(isDev()).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should return false when __DEV__ is undefined', () => {
|
|
34
|
+
delete (globalThis as any).__DEV__;
|
|
35
|
+
expect(isDev()).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('devWarn', () => {
|
|
40
|
+
it('should log warning when in development mode', () => {
|
|
41
|
+
(globalThis as any).__DEV__ = true;
|
|
42
|
+
|
|
43
|
+
devWarn('Test warning', { data: 'test' });
|
|
44
|
+
|
|
45
|
+
expect(mockConsoleWarn).toHaveBeenCalledWith('Test warning', { data: 'test' });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should not log warning when not in development mode', () => {
|
|
49
|
+
(globalThis as any).__DEV__ = false;
|
|
50
|
+
|
|
51
|
+
devWarn('Test warning', { data: 'test' });
|
|
52
|
+
|
|
53
|
+
expect(mockConsoleWarn).not.toHaveBeenCalled();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('devError', () => {
|
|
58
|
+
it('should log error when in development mode', () => {
|
|
59
|
+
(globalThis as any).__DEV__ = true;
|
|
60
|
+
|
|
61
|
+
devError('Test error', new Error('test'));
|
|
62
|
+
|
|
63
|
+
expect(mockConsoleError).toHaveBeenCalledWith('Test error', new Error('test'));
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should not log error when not in development mode', () => {
|
|
67
|
+
(globalThis as any).__DEV__ = false;
|
|
68
|
+
|
|
69
|
+
devError('Test error', new Error('test'));
|
|
70
|
+
|
|
71
|
+
expect(mockConsoleError).not.toHaveBeenCalled();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('devLog', () => {
|
|
76
|
+
it('should log info when in development mode', () => {
|
|
77
|
+
(globalThis as any).__DEV__ = true;
|
|
78
|
+
|
|
79
|
+
devLog('Test log', { info: 'test' });
|
|
80
|
+
|
|
81
|
+
expect(mockConsoleLog).toHaveBeenCalledWith('Test log', { info: 'test' });
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should not log info when not in development mode', () => {
|
|
85
|
+
(globalThis as any).__DEV__ = false;
|
|
86
|
+
|
|
87
|
+
devLog('Test log', { info: 'test' });
|
|
88
|
+
|
|
89
|
+
expect(mockConsoleLog).not.toHaveBeenCalled();
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
afterEach(() => {
|
|
94
|
+
// Clean up __DEV__ after each test
|
|
95
|
+
delete (globalThis as any).__DEV__;
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Development utilities
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Check if running in development mode
|
|
7
|
+
*/
|
|
8
|
+
export const isDev = (): boolean => {
|
|
9
|
+
return (globalThis as any).__DEV__ === true;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Log warning in development mode only
|
|
14
|
+
*/
|
|
15
|
+
export const devWarn = (message: string, ...args: any[]): void => {
|
|
16
|
+
if (isDev()) {
|
|
17
|
+
console.warn(message, ...args);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Log error in development mode only
|
|
23
|
+
*/
|
|
24
|
+
export const devError = (message: string, ...args: any[]): void => {
|
|
25
|
+
if (isDev()) {
|
|
26
|
+
console.error(message, ...args);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Log info in development mode only
|
|
32
|
+
*/
|
|
33
|
+
export const devLog = (message: string, ...args: any[]): void => {
|
|
34
|
+
if (isDev()) {
|
|
35
|
+
console.log(message, ...args);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
@@ -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
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage Key Value Object
|
|
3
|
+
*
|
|
4
|
+
* Domain-Driven Design: Value Object for storage keys
|
|
5
|
+
* Ensures type safety and prevents invalid key usage
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Storage key with dynamic suffix
|
|
10
|
+
*/
|
|
11
|
+
export type DynamicStorageKey = {
|
|
12
|
+
base: string;
|
|
13
|
+
suffix: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Helper to create user-specific storage key
|
|
18
|
+
*
|
|
19
|
+
* @param baseKey Base storage key
|
|
20
|
+
* @param userId User identifier
|
|
21
|
+
* @returns User-specific key
|
|
22
|
+
*/
|
|
23
|
+
export const createUserKey = (baseKey: string, userId: string): string => {
|
|
24
|
+
return `${baseKey}_${userId}`;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Helper to create app-specific storage key
|
|
29
|
+
*
|
|
30
|
+
* @param baseKey Base storage key
|
|
31
|
+
* @param appName App identifier
|
|
32
|
+
* @returns App-specific key
|
|
33
|
+
*/
|
|
34
|
+
export const createAppKey = (baseKey: string, appName: string): string => {
|
|
35
|
+
return `${appName}_${baseKey}`;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Helper to create namespaced storage key
|
|
40
|
+
*
|
|
41
|
+
* @param namespace Key namespace
|
|
42
|
+
* @param key Specific key
|
|
43
|
+
* @returns Namespaced key
|
|
44
|
+
*/
|
|
45
|
+
export const createNamespacedKey = (namespace: string, key: string): string => {
|
|
46
|
+
return `${namespace}:${key}`;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Common storage keys for cross-app usage
|
|
51
|
+
* Generic keys that can be used across multiple applications
|
|
52
|
+
*/
|
|
53
|
+
export enum StorageKey {
|
|
54
|
+
USER_PREFERENCES = '@user_preferences',
|
|
55
|
+
APP_SETTINGS = '@app_settings',
|
|
56
|
+
LANGUAGE = '@language',
|
|
57
|
+
UI_PREFERENCES = '@ui_preferences',
|
|
58
|
+
QUERY_CACHE = '@query_cache',
|
|
59
|
+
DATA_CACHE = '@data_cache',
|
|
60
|
+
}
|