@umituz/react-native-design-system 4.23.82 → 4.23.84

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 (29) hide show
  1. package/package.json +1 -1
  2. package/src/atoms/input/hooks/useInputState.ts +2 -4
  3. package/src/image/presentation/components/editor/text-editor/TextTransformTab.tsx +40 -152
  4. package/src/image/presentation/components/editor/text-editor/components/TransformButtonRow.tsx +124 -0
  5. package/src/layouts/Grid/Grid.tsx +16 -11
  6. package/src/media/domain/utils/FileValidator.ts +156 -0
  7. package/src/media/infrastructure/services/MediaPickerService.ts +18 -57
  8. package/src/media/infrastructure/utils/PermissionManager.ts +92 -0
  9. package/src/media/infrastructure/utils/file-media-utils.ts +25 -8
  10. package/src/media/presentation/hooks/useMedia.ts +5 -4
  11. package/src/molecules/alerts/AlertBanner.tsx +9 -25
  12. package/src/molecules/alerts/AlertInline.tsx +4 -23
  13. package/src/molecules/alerts/AlertModal.tsx +4 -11
  14. package/src/molecules/alerts/AlertToast.tsx +14 -13
  15. package/src/molecules/alerts/utils/alertUtils.ts +133 -0
  16. package/src/molecules/calendar/infrastructure/storage/CalendarStore.ts +65 -25
  17. package/src/molecules/countdown/hooks/useCountdown.ts +13 -5
  18. package/src/molecules/swipe-actions/domain/entities/SwipeAction.ts +15 -123
  19. package/src/molecules/swipe-actions/domain/utils/swipeActionHelpers.ts +109 -0
  20. package/src/molecules/swipe-actions/domain/utils/swipeActionValidator.ts +54 -0
  21. package/src/molecules/swipe-actions/presentation/components/SwipeActionButton.tsx +24 -6
  22. package/src/offline/presentation/hooks/useOffline.ts +2 -1
  23. package/src/storage/domain/utils/devUtils.ts +7 -6
  24. package/src/storage/infrastructure/adapters/StorageService.ts +0 -9
  25. package/src/storage/infrastructure/repositories/BaseStorageOperations.ts +0 -3
  26. package/src/tanstack/domain/utils/MetricsCalculator.ts +103 -0
  27. package/src/tanstack/infrastructure/monitoring/DevMonitor.ts +35 -29
  28. package/src/timezone/infrastructure/utils/SimpleCache.ts +24 -2
  29. package/src/molecules/alerts/utils/alertToastHelpers.ts +0 -70
@@ -9,12 +9,14 @@
9
9
  import type { Query, QueryClient } from '@tanstack/react-query';
10
10
  import type { QueryMetrics, CacheStats, DevMonitorOptions } from './DevMonitor.types';
11
11
  import { DevMonitorLogger } from './DevMonitorLogger';
12
+ import { MetricsCalculator } from '../../domain/utils/MetricsCalculator';
12
13
 
13
14
  class DevMonitorClass {
14
15
  private metrics: Map<string, QueryMetrics> = new Map();
15
16
  private queryClient: QueryClient | null = null;
16
17
  private options: Required<DevMonitorOptions>;
17
18
  private statsInterval: ReturnType<typeof setInterval> | null = null;
19
+ private cacheSubscription: (() => void) | null = null;
18
20
  private isEnabled: boolean;
19
21
 
20
22
  constructor(options: DevMonitorOptions = {}) {
@@ -38,37 +40,22 @@ class DevMonitorClass {
38
40
  this.startStatsLogging();
39
41
  }
40
42
 
41
- private getQueryKeyString(queryKey: readonly unknown[]): string {
42
- return JSON.stringify(queryKey);
43
- }
44
-
45
43
  private trackQuery(query: Query): void {
46
44
  if (!this.isEnabled) return;
47
45
 
48
- const queryKeyString = this.getQueryKeyString(query.queryKey);
49
-
50
- if (!this.metrics.has(queryKeyString)) {
51
- this.metrics.set(queryKeyString, {
52
- queryKey: query.queryKey,
53
- fetchCount: 0,
54
- totalFetchTime: 0,
55
- averageFetchTime: 0,
56
- slowFetchCount: 0,
57
- lastFetchTime: null,
58
- });
59
- }
60
-
61
- const metrics = this.metrics.get(queryKeyString)!;
62
- const fetchTime = Date.now() - (query.state.dataUpdatedAt ?? Date.now());
46
+ const queryKeyString = MetricsCalculator.getQueryKeyString(query.queryKey);
47
+ const currentMetrics = this.metrics.get(queryKeyString) ?? null;
48
+ const updatedMetrics = MetricsCalculator.calculateQueryMetrics(
49
+ query,
50
+ currentMetrics,
51
+ this.options
52
+ );
63
53
 
64
- metrics.fetchCount++;
65
- metrics.totalFetchTime += fetchTime;
66
- metrics.averageFetchTime = metrics.totalFetchTime / metrics.fetchCount;
67
- metrics.lastFetchTime = fetchTime;
54
+ this.metrics.set(queryKeyString, updatedMetrics);
68
55
 
69
- if (fetchTime > this.options.slowQueryThreshold) {
70
- metrics.slowFetchCount++;
71
- if (this.options.enableLogging) {
56
+ if (this.options.enableLogging && updatedMetrics.slowFetchCount > 0) {
57
+ const fetchTime = MetricsCalculator.calculateFetchTime(query);
58
+ if (MetricsCalculator.isSlowQuery(fetchTime, this.options.slowQueryThreshold)) {
72
59
  DevMonitorLogger.logSlowQuery(queryKeyString, fetchTime);
73
60
  }
74
61
  }
@@ -80,8 +67,13 @@ class DevMonitorClass {
80
67
  attach(queryClient: QueryClient): void {
81
68
  if (!this.isEnabled) return;
82
69
 
70
+ // Detach from previous client if attached
71
+ if (this.cacheSubscription) {
72
+ this.detach();
73
+ }
74
+
83
75
  this.queryClient = queryClient;
84
- queryClient.getQueryCache().subscribe((event) => {
76
+ this.cacheSubscription = queryClient.getQueryCache().subscribe((event) => {
85
77
  if (event.query) {
86
78
  this.trackQuery(event.query as Query);
87
79
  }
@@ -92,6 +84,20 @@ class DevMonitorClass {
92
84
  }
93
85
  }
94
86
 
87
+ /**
88
+ * Detach monitor from query client
89
+ */
90
+ detach(): void {
91
+ if (!this.isEnabled) return;
92
+
93
+ if (this.cacheSubscription) {
94
+ this.cacheSubscription();
95
+ this.cacheSubscription = null;
96
+ }
97
+
98
+ this.queryClient = null;
99
+ }
100
+
95
101
  /**
96
102
  * Get all query metrics
97
103
  */
@@ -105,7 +111,7 @@ class DevMonitorClass {
105
111
  */
106
112
  getQueryMetrics(queryKey: readonly unknown[]): QueryMetrics | undefined {
107
113
  if (!this.isEnabled) return undefined;
108
- const queryKeyString = this.getQueryKeyString(queryKey);
114
+ const queryKeyString = MetricsCalculator.getQueryKeyString(queryKey);
109
115
  return this.metrics.get(queryKeyString);
110
116
  }
111
117
 
@@ -179,9 +185,9 @@ class DevMonitorClass {
179
185
  */
180
186
  reset(): void {
181
187
  if (!this.isEnabled) return;
188
+ this.detach();
182
189
  this.stopStatsLogging();
183
190
  this.clear();
184
- this.queryClient = null;
185
191
  if (this.options.enableLogging) {
186
192
  DevMonitorLogger.logReset();
187
193
  }
@@ -13,10 +13,22 @@ interface CacheEntry<T> {
13
13
  export class SimpleCache<T> {
14
14
  private cache = new Map<string, CacheEntry<T>>();
15
15
  private defaultTTL: number;
16
+ private cleanupTimeout: ReturnType<typeof setTimeout> | null = null;
16
17
 
17
18
  constructor(defaultTTL: number = 60000) {
18
19
  this.defaultTTL = defaultTTL;
19
- this.cleanup();
20
+ this.scheduleCleanup();
21
+ }
22
+
23
+ /**
24
+ * Destroy the cache and stop cleanup timer
25
+ */
26
+ destroy(): void {
27
+ if (this.cleanupTimeout) {
28
+ clearTimeout(this.cleanupTimeout);
29
+ this.cleanupTimeout = null;
30
+ }
31
+ this.cache.clear();
20
32
  }
21
33
 
22
34
  set(key: string, value: T, ttl?: number): void {
@@ -58,7 +70,17 @@ export class SimpleCache<T> {
58
70
  this.cache.delete(key);
59
71
  }
60
72
  }
73
+ }
74
+
75
+ private scheduleCleanup(): void {
76
+ if (this.cleanupTimeout) {
77
+ clearTimeout(this.cleanupTimeout);
78
+ }
79
+
80
+ this.cleanup();
61
81
 
62
- setTimeout(() => this.cleanup(), 60000);
82
+ this.cleanupTimeout = setTimeout(() => {
83
+ this.scheduleCleanup();
84
+ }, 60000);
63
85
  }
64
86
  }
@@ -1,70 +0,0 @@
1
- /**
2
- * Alert Toast Helper Functions
3
- * Style and color helpers for alert toast component
4
- */
5
-
6
- import { AlertType } from '../AlertTypes';
7
- import type { DesignTokens } from '../../../theme';
8
- import type { StyleProp, ViewStyle } from 'react-native';
9
-
10
- /**
11
- * Gets background color for alert type
12
- *
13
- * @param type - Alert type
14
- * @param tokens - Design tokens
15
- * @returns Background color string
16
- */
17
- export function getAlertBackgroundColor(type: AlertType, tokens: DesignTokens): string {
18
- const colors = {
19
- [AlertType.SUCCESS]: tokens.colors.success,
20
- [AlertType.ERROR]: tokens.colors.error,
21
- [AlertType.WARNING]: tokens.colors.warning,
22
- [AlertType.INFO]: tokens.colors.info,
23
- };
24
- return colors[type] || tokens.colors.backgroundSecondary;
25
- }
26
-
27
- /**
28
- * Gets action button style
29
- *
30
- * @param style - Button style type
31
- * @param tokens - Design tokens
32
- * @returns Style object
33
- */
34
- export function getActionButtonStyle(
35
- style: 'primary' | 'secondary' | 'destructive' | undefined,
36
- tokens: DesignTokens
37
- ): StyleProp<ViewStyle> {
38
- if (style === 'secondary') {
39
- return {
40
- backgroundColor: undefined,
41
- borderWidth: 1,
42
- borderColor: tokens.colors.textInverse,
43
- };
44
- }
45
-
46
- const colors = {
47
- primary: tokens.colors.backgroundPrimary,
48
- destructive: tokens.colors.error,
49
- };
50
- return { backgroundColor: colors[style as keyof typeof colors] || tokens.colors.backgroundSecondary };
51
- }
52
-
53
- /**
54
- * Gets action text color
55
- *
56
- * @param style - Button style type
57
- * @param tokens - Design tokens
58
- * @returns Text color string
59
- */
60
- export function getActionTextColor(
61
- style: 'primary' | 'secondary' | 'destructive' | undefined,
62
- tokens: DesignTokens
63
- ): string {
64
- return style === 'primary' ? tokens.colors.textPrimary : tokens.colors.textInverse;
65
- }
66
-
67
- /**
68
- * Default toast duration in milliseconds
69
- */
70
- export const DEFAULT_TOAST_DURATION = 3000;