@umituz/react-native-firebase 2.4.100 → 2.6.0

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 (23) hide show
  1. package/package.json +1 -1
  2. package/src/domains/firestore/index.ts +11 -58
  3. package/src/domains/firestore/infrastructure/repositories/BasePaginatedRepository.ts +1 -7
  4. package/src/domains/firestore/infrastructure/repositories/BaseQueryRepository.ts +8 -34
  5. package/src/domains/firestore/infrastructure/repositories/BaseRepository.ts +9 -48
  6. package/src/domains/firestore/presentation/hooks/index.ts +0 -10
  7. package/src/shared/domain/utils/calculation.util.ts +17 -305
  8. package/src/shared/domain/utils/index.ts +0 -5
  9. package/src/shared/infrastructure/config/state/FirebaseClientState.ts +34 -12
  10. package/src/domains/firestore/domain/constants/QuotaLimits.ts +0 -101
  11. package/src/domains/firestore/domain/entities/QuotaMetrics.ts +0 -26
  12. package/src/domains/firestore/domain/entities/RequestLog.ts +0 -28
  13. package/src/domains/firestore/domain/services/QuotaCalculator.ts +0 -71
  14. package/src/domains/firestore/infrastructure/middleware/QueryDeduplicationMiddleware.ts +0 -312
  15. package/src/domains/firestore/infrastructure/middleware/QuotaTrackingMiddleware.ts +0 -95
  16. package/src/domains/firestore/infrastructure/services/RequestLoggerService.ts +0 -165
  17. package/src/domains/firestore/presentation/hooks/useSmartFirestoreSnapshot.ts +0 -361
  18. package/src/domains/firestore/presentation/query-keys/createFirestoreKeys.ts +0 -32
  19. package/src/domains/firestore/presentation/query-keys/index.ts +0 -1
  20. package/src/domains/firestore/utils/deduplication/pending-query-manager.util.ts +0 -119
  21. package/src/domains/firestore/utils/deduplication/query-key-generator.util.ts +0 -34
  22. package/src/domains/firestore/utils/deduplication/timer-manager.util.ts +0 -83
  23. package/src/shared/infrastructure/config/base/ClientStateManager.ts +0 -82
@@ -1,20 +1,42 @@
1
- /**
2
- * Firebase Client State Manager
3
- * Manages the state of Firebase initialization
4
- *
5
- * Single Responsibility: Only manages initialization state
6
- * Uses generic ClientStateManager for shared functionality
7
- */
8
-
9
1
  import type { FirebaseApp } from 'firebase/app';
10
- import { ClientStateManager } from '../base/ClientStateManager';
11
2
 
12
- export class FirebaseClientState extends ClientStateManager<FirebaseApp> {
3
+ export class FirebaseClientState {
4
+ private app: FirebaseApp | null = null;
5
+ private initializationError: string | null = null;
6
+ private isInitializedFlag = false;
7
+
13
8
  getApp(): FirebaseApp | null {
14
- return this.getInstance();
9
+ return this.app;
15
10
  }
16
11
 
17
12
  setApp(app: FirebaseApp | null): void {
18
- this.setInstance(app);
13
+ this.app = app;
14
+ this.isInitializedFlag = app !== null;
15
+ }
16
+
17
+ setInstance(app: FirebaseApp | null): void {
18
+ this.setApp(app);
19
+ }
20
+
21
+ getInstance(): FirebaseApp | null {
22
+ return this.getApp();
23
+ }
24
+
25
+ isInitialized(): boolean {
26
+ return this.isInitializedFlag;
27
+ }
28
+
29
+ getInitializationError(): string | null {
30
+ return this.initializationError;
31
+ }
32
+
33
+ setInitializationError(error: string | null): void {
34
+ this.initializationError = error;
35
+ }
36
+
37
+ reset(): void {
38
+ this.app = null;
39
+ this.initializationError = null;
40
+ this.isInitializedFlag = false;
19
41
  }
20
42
  }
@@ -1,101 +0,0 @@
1
- /**
2
- * Quota Limit Constants
3
- * Domain layer - Default Firestore quota limits
4
- *
5
- * General-purpose constants for any app using Firestore
6
- * Based on Firestore free tier and pricing documentation
7
- */
8
-
9
- import { calculatePercentage, calculateRemaining } from '../../../../shared/domain/utils/calculation.util';
10
-
11
- /**
12
- * Firestore free tier daily limits
13
- * https://firebase.google.com/docs/firestore/quotas
14
- */
15
- export const FREE_TIER_LIMITS = {
16
- /**
17
- * Daily read operations (documents)
18
- * Free tier: 50,000 reads/day
19
- */
20
- DAILY_READS: 50_000,
21
-
22
- /**
23
- * Daily write operations (documents)
24
- * Free tier: 20,000 writes/day
25
- */
26
- DAILY_WRITES: 20_000,
27
-
28
- /**
29
- * Daily delete operations (documents)
30
- * Free tier: 20,000 deletes/day
31
- */
32
- DAILY_DELETES: 20_000,
33
-
34
- /**
35
- * Stored data (GB)
36
- * Free tier: 1 GB
37
- */
38
- STORAGE_GB: 1,
39
- } as const;
40
-
41
- /**
42
- * Quota warning thresholds (percentage of limit)
43
- * Apps can use these to show warnings before hitting limits
44
- */
45
- export const QUOTA_THRESHOLDS = {
46
- /**
47
- * Warning threshold (80% of limit)
48
- * Show warning to user
49
- */
50
- WARNING: 0.8,
51
-
52
- /**
53
- * Critical threshold (95% of limit)
54
- * Show critical alert, consider disabling features
55
- */
56
- CRITICAL: 0.95,
57
-
58
- /**
59
- * Emergency threshold (98% of limit)
60
- * Disable non-essential features
61
- */
62
- EMERGENCY: 0.98,
63
- } as const;
64
-
65
- /**
66
- * Calculate quota usage percentage
67
- * Optimized: Uses centralized calculation utility
68
- * @param current - Current usage count
69
- * @param limit - Total limit
70
- * @returns Percentage (0-1)
71
- */
72
- export function calculateQuotaUsage(current: number, limit: number): number {
73
- return calculatePercentage(current, limit);
74
- }
75
-
76
- /**
77
- * Check if quota threshold is reached
78
- * @param current - Current usage count
79
- * @param limit - Total limit
80
- * @param threshold - Threshold to check (0-1)
81
- * @returns true if threshold is reached
82
- */
83
- export function isQuotaThresholdReached(
84
- current: number,
85
- limit: number,
86
- threshold: number,
87
- ): boolean {
88
- const usage = calculateQuotaUsage(current, limit);
89
- return usage >= threshold;
90
- }
91
-
92
- /**
93
- * Get remaining quota
94
- * Optimized: Uses centralized calculation utility
95
- * @param current - Current usage count
96
- * @param limit - Total limit
97
- * @returns Remaining quota count
98
- */
99
- export function getRemainingQuota(current: number, limit: number): number {
100
- return calculateRemaining(current, limit);
101
- }
@@ -1,26 +0,0 @@
1
- /**
2
- * Quota Metrics Types
3
- */
4
-
5
- export interface QuotaMetrics {
6
- readCount: number;
7
- writeCount: number;
8
- deleteCount: number;
9
- lastResetDate: string;
10
- }
11
-
12
- export interface QuotaLimits {
13
- dailyReadLimit: number;
14
- dailyWriteLimit: number;
15
- dailyDeleteLimit: number;
16
- }
17
-
18
- export interface QuotaStatus {
19
- metrics: QuotaMetrics;
20
- limits: QuotaLimits;
21
- readPercentage: number;
22
- writePercentage: number;
23
- deletePercentage: number;
24
- isNearLimit: boolean;
25
- isOverLimit: boolean;
26
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * Request Log Types
3
- */
4
-
5
- export type RequestType = 'read' | 'write' | 'delete' | 'listener';
6
-
7
- export interface RequestLog {
8
- id: string;
9
- type: RequestType;
10
- collection: string;
11
- documentId?: string;
12
- cached: boolean;
13
- success: boolean;
14
- error?: string;
15
- duration?: number;
16
- timestamp: number;
17
- }
18
-
19
- export interface RequestStats {
20
- totalRequests: number;
21
- readRequests: number;
22
- writeRequests: number;
23
- deleteRequests: number;
24
- listenerRequests: number;
25
- cachedRequests: number;
26
- failedRequests: number;
27
- averageDuration: number;
28
- }
@@ -1,71 +0,0 @@
1
- /**
2
- * Quota Calculator Service
3
- * Domain service for calculating quota usage and status
4
- */
5
-
6
- import type { QuotaMetrics, QuotaLimits, QuotaStatus } from '../entities/QuotaMetrics';
7
- import { FREE_TIER_LIMITS, QUOTA_THRESHOLDS, calculateQuotaUsage } from '../constants/QuotaLimits';
8
-
9
- /**
10
- * Default quota limits (Firebase Spark Plan)
11
- * Can be overridden via configuration
12
- */
13
- const DEFAULT_QUOTA_LIMITS: QuotaLimits = {
14
- dailyReadLimit: FREE_TIER_LIMITS.DAILY_READS,
15
- dailyWriteLimit: FREE_TIER_LIMITS.DAILY_WRITES,
16
- dailyDeleteLimit: FREE_TIER_LIMITS.DAILY_DELETES,
17
- };
18
-
19
- export class QuotaCalculator {
20
- /**
21
- * Calculate quota status from metrics and limits
22
- */
23
- static calculateStatus(
24
- metrics: QuotaMetrics,
25
- limits: QuotaLimits = DEFAULT_QUOTA_LIMITS,
26
- ): QuotaStatus {
27
- const readPercentage = calculateQuotaUsage(metrics.readCount, limits.dailyReadLimit) * 100;
28
- const writePercentage = calculateQuotaUsage(metrics.writeCount, limits.dailyWriteLimit) * 100;
29
- const deletePercentage = calculateQuotaUsage(metrics.deleteCount, limits.dailyDeleteLimit) * 100;
30
-
31
- const warningThreshold = QUOTA_THRESHOLDS.WARNING * 100;
32
- const isNearLimit =
33
- readPercentage >= warningThreshold ||
34
- writePercentage >= warningThreshold ||
35
- deletePercentage >= warningThreshold;
36
-
37
- const isOverLimit =
38
- readPercentage >= 100 ||
39
- writePercentage >= 100 ||
40
- deletePercentage >= 100;
41
-
42
- return {
43
- metrics,
44
- limits,
45
- readPercentage,
46
- writePercentage,
47
- deletePercentage,
48
- isNearLimit,
49
- isOverLimit,
50
- };
51
- }
52
-
53
- /**
54
- * Get default quota limits
55
- */
56
- static getDefaultLimits(): QuotaLimits {
57
- return { ...DEFAULT_QUOTA_LIMITS };
58
- }
59
-
60
- /**
61
- * Check if metrics are within limits
62
- */
63
- static isWithinLimits(
64
- metrics: QuotaMetrics,
65
- limits: QuotaLimits = DEFAULT_QUOTA_LIMITS,
66
- ): boolean {
67
- const status = this.calculateStatus(metrics, limits);
68
- return !status.isOverLimit;
69
- }
70
- }
71
-
@@ -1,312 +0,0 @@
1
- /**
2
- * Query Deduplication Middleware (Enhanced)
3
- *
4
- * Prevents duplicate Firestore queries within a configurable time window
5
- * with quota-aware adaptive deduplication
6
- *
7
- * FEATURES:
8
- * - Configurable deduplication window (default: 10s, was 1s)
9
- * - Quota-aware adaptive window adjustment
10
- * - Statistics and monitoring
11
- * - Memory leak prevention
12
- * - Automatic cleanup optimization
13
- *
14
- * COST SAVINGS: ~90% reduction in duplicate query reads
15
- */
16
-
17
- import type { QueryKey } from '../../utils/deduplication/query-key-generator.util';
18
- import { generateQueryKey } from '../../utils/deduplication/query-key-generator.util';
19
- import { PendingQueryManager } from '../../utils/deduplication/pending-query-manager.util';
20
- import { TimerManager } from '../../utils/deduplication/timer-manager.util';
21
-
22
- /**
23
- * Default configuration
24
- * Optimized for cost savings while maintaining freshness
25
- */
26
- const DEFAULT_DEDUPLICATION_WINDOW_MS = 10000; // 10s (was 1s)
27
- const DEFAULT_CLEANUP_INTERVAL_MS = 15000; // 15s (was 3s)
28
-
29
- /**
30
- * Quota-based window adjustment thresholds
31
- */
32
- const QUOTA_THRESHOLDS = {
33
- HIGH_USAGE: 0.80, // 80% - extend window to 60s (1 min)
34
- MEDIUM_USAGE: 0.60, // 60% - extend window to 20s
35
- NORMAL: 0.50, // < 50% - use default 10s
36
- } as const;
37
-
38
- /**
39
- * Deduplication statistics
40
- */
41
- export interface DeduplicationStatistics {
42
- /** Total queries processed */
43
- totalQueries: number;
44
- /** Queries served from cache (deduplicated) */
45
- cachedQueries: number;
46
- /** Queries executed (not cached) */
47
- executedQueries: number;
48
- /** Current deduplication window in ms */
49
- currentWindowMs: number;
50
- /** Cache hit rate (0-1) */
51
- cacheHitRate: number;
52
- /** Memory usage (number of cached queries) */
53
- pendingQueries: number;
54
- }
55
-
56
- /**
57
- * Configuration options for deduplication middleware
58
- */
59
- export interface QueryDeduplicationConfig {
60
- /** Base deduplication window in ms (default: 10000) */
61
- baseWindowMs?: number;
62
- /** Cleanup interval in ms (default: 15000) */
63
- cleanupIntervalMs?: number;
64
- /** Enable quota-aware adaptive window (default: true) */
65
- quotaAware?: boolean;
66
- /** Maximum window size in ms (default: 60000 = 1 minute) */
67
- maxWindowMs?: number;
68
- /** Minimum window size in ms (default: 1000 = 1 second) */
69
- minWindowMs?: number;
70
- }
71
-
72
- /**
73
- * Enhanced Query Deduplication Middleware
74
- * Prevents duplicate queries with adaptive quota-aware behavior
75
- */
76
- export class QueryDeduplicationMiddleware {
77
- private readonly queryManager: PendingQueryManager;
78
- private readonly timerManager: TimerManager;
79
- private readonly baseWindowMs: number;
80
- private readonly maxWindowMs: number;
81
- private readonly minWindowMs: number;
82
- private readonly quotaAware: boolean;
83
- private destroyed = false;
84
-
85
- // Statistics tracking
86
- private stats: DeduplicationStatistics = {
87
- totalQueries: 0,
88
- cachedQueries: 0,
89
- executedQueries: 0,
90
- currentWindowMs: DEFAULT_DEDUPLICATION_WINDOW_MS,
91
- cacheHitRate: 0,
92
- pendingQueries: 0,
93
- };
94
-
95
- constructor(config: QueryDeduplicationConfig = {}) {
96
- this.baseWindowMs = config.baseWindowMs ?? DEFAULT_DEDUPLICATION_WINDOW_MS;
97
- this.maxWindowMs = config.maxWindowMs ?? 60000; // 1 minute max
98
- this.minWindowMs = config.minWindowMs ?? 1000; // 1 second min
99
- this.quotaAware = config.quotaAware ?? true;
100
-
101
- const cleanupIntervalMs = config.cleanupIntervalMs ?? DEFAULT_CLEANUP_INTERVAL_MS;
102
-
103
- this.queryManager = new PendingQueryManager(this.baseWindowMs);
104
- this.timerManager = new TimerManager({
105
- cleanupIntervalMs,
106
- onCleanup: () => {
107
- if (!this.destroyed) {
108
- this.queryManager.cleanup();
109
- this.updateStats();
110
- }
111
- },
112
- });
113
- this.timerManager.start();
114
- }
115
-
116
- /**
117
- * Execute query with deduplication
118
- * Returns cached result if available within window, otherwise executes
119
- */
120
- async deduplicate<T>(
121
- queryKey: QueryKey,
122
- queryFn: () => Promise<T>,
123
- ): Promise<T> {
124
- if (this.destroyed) {
125
- // If middleware is destroyed, execute query directly without deduplication
126
- return queryFn();
127
- }
128
-
129
- this.stats.totalQueries++;
130
- const key = generateQueryKey(queryKey);
131
-
132
- // Check for existing promise (atomic get-or-create pattern)
133
- const existingPromise = this.queryManager.get(key);
134
- if (existingPromise) {
135
- this.stats.cachedQueries++;
136
- this.updateCacheHitRate();
137
- return existingPromise as Promise<T>;
138
- }
139
-
140
- // Create promise with cleanup on completion
141
- this.stats.executedQueries++;
142
- const promise = (async () => {
143
- try {
144
- return await queryFn();
145
- } finally {
146
- // Immediate cleanup after completion (success or error)
147
- this.queryManager.remove(key);
148
- this.stats.pendingQueries = this.queryManager.size();
149
- }
150
- })();
151
-
152
- // Add before any await - this prevents race between check and add
153
- this.queryManager.add(key, promise);
154
- this.stats.pendingQueries = this.queryManager.size();
155
-
156
- return promise;
157
- }
158
-
159
- /**
160
- * Adjust deduplication window based on quota usage
161
- * Call this periodically with current quota percentage
162
- *
163
- * @param quotaPercentage - Current quota usage (0-1)
164
- *
165
- * @example
166
- * ```typescript
167
- * const quotaStatus = getQuotaStatus();
168
- * middleware.adjustWindowForQuota(quotaStatus.readPercentage / 100);
169
- * ```
170
- */
171
- adjustWindowForQuota(quotaPercentage: number): void {
172
- if (!this.quotaAware || this.destroyed) {
173
- return;
174
- }
175
-
176
- let newWindowMs: number;
177
-
178
- if (quotaPercentage >= QUOTA_THRESHOLDS.HIGH_USAGE) {
179
- // High usage: extend window to maximum (1 minute)
180
- newWindowMs = this.maxWindowMs;
181
- } else if (quotaPercentage >= QUOTA_THRESHOLDS.MEDIUM_USAGE) {
182
- // Medium usage: extend window to 20s
183
- newWindowMs = Math.min(20000, this.maxWindowMs);
184
- } else {
185
- // Normal usage: use base window (10s)
186
- newWindowMs = this.baseWindowMs;
187
- }
188
-
189
- // Clamp to min/max bounds
190
- newWindowMs = Math.max(this.minWindowMs, Math.min(newWindowMs, this.maxWindowMs));
191
-
192
- // Only update if changed
193
- if (newWindowMs !== this.stats.currentWindowMs) {
194
- this.queryManager.setWindow(newWindowMs);
195
- this.stats.currentWindowMs = newWindowMs;
196
-
197
- if (__DEV__) {
198
- console.log(
199
- `[Deduplication] Adjusted window to ${newWindowMs}ms ` +
200
- `(quota: ${(quotaPercentage * 100).toFixed(1)}%)`
201
- );
202
- }
203
- }
204
- }
205
-
206
- /**
207
- * Get current deduplication statistics
208
- */
209
- getStatistics(): DeduplicationStatistics {
210
- return { ...this.stats };
211
- }
212
-
213
- /**
214
- * Reset statistics
215
- */
216
- resetStatistics(): void {
217
- this.stats = {
218
- totalQueries: 0,
219
- cachedQueries: 0,
220
- executedQueries: 0,
221
- currentWindowMs: this.stats.currentWindowMs,
222
- cacheHitRate: 0,
223
- pendingQueries: this.queryManager.size(),
224
- };
225
- }
226
-
227
- /**
228
- * Update cache hit rate
229
- */
230
- private updateCacheHitRate(): void {
231
- this.stats.cacheHitRate =
232
- this.stats.totalQueries > 0
233
- ? this.stats.cachedQueries / this.stats.totalQueries
234
- : 0;
235
- }
236
-
237
- /**
238
- * Update statistics
239
- */
240
- private updateStats(): void {
241
- this.stats.pendingQueries = this.queryManager.size();
242
- this.updateCacheHitRate();
243
- }
244
-
245
- /**
246
- * Clear all cached queries
247
- */
248
- clear(): void {
249
- this.queryManager.clear();
250
- this.stats.pendingQueries = 0;
251
- }
252
-
253
- /**
254
- * Destroy middleware and cleanup resources
255
- */
256
- destroy(): void {
257
- this.destroyed = true;
258
- this.timerManager.destroy();
259
- this.queryManager.clear();
260
- this.stats.pendingQueries = 0;
261
- }
262
-
263
- /**
264
- * Get number of pending queries
265
- */
266
- getPendingCount(): number {
267
- return this.queryManager.size();
268
- }
269
- }
270
-
271
- /**
272
- * Default singleton instance with recommended settings
273
- */
274
- export const queryDeduplicationMiddleware = new QueryDeduplicationMiddleware({
275
- baseWindowMs: DEFAULT_DEDUPLICATION_WINDOW_MS,
276
- cleanupIntervalMs: DEFAULT_CLEANUP_INTERVAL_MS,
277
- quotaAware: true,
278
- maxWindowMs: 60000, // 1 minute
279
- minWindowMs: 1000, // 1 second
280
- });
281
-
282
- /**
283
- * Helper function to integrate deduplication with quota tracking
284
- * Automatically adjusts window based on quota usage
285
- *
286
- * Note: This is NOT a React hook, but a helper function.
287
- * Call this from your own hook or effect as needed.
288
- *
289
- * @example
290
- * ```typescript
291
- * // In your own hook or component:
292
- * useEffect(() => {
293
- * syncDeduplicationWithQuota(queryDeduplicationMiddleware, quotaMiddleware, quotaLimits);
294
- * }, [quotaMiddleware.getCounts().reads]);
295
- * ```
296
- */
297
- export function syncDeduplicationWithQuota(
298
- deduplication: QueryDeduplicationMiddleware,
299
- quotaMiddleware: { getCounts: () => { reads: number; writes: number; deletes: number } },
300
- quotaLimits: { dailyReadLimit: number }
301
- ): void {
302
- // Adjust deduplication window based on quota
303
- const counts = quotaMiddleware.getCounts();
304
- const quotaPercentage = counts.reads / quotaLimits.dailyReadLimit;
305
- deduplication.adjustWindowForQuota(quotaPercentage);
306
- }
307
-
308
- /**
309
- * @deprecated Use syncDeduplicationWithQuota instead (not a hook)
310
- * This will be removed in a future version
311
- */
312
- export const useDeduplicationWithQuota = syncDeduplicationWithQuota;
@@ -1,95 +0,0 @@
1
- /**
2
- * Quota Tracking Middleware
3
- * Tracks Firestore operations for quota monitoring
4
- */
5
-
6
- interface OperationInfo {
7
- type: 'read' | 'write' | 'delete';
8
- collection: string;
9
- count: number;
10
- cached: boolean;
11
- }
12
-
13
- export class QuotaTrackingMiddleware {
14
- private readCount = 0;
15
- private writeCount = 0;
16
- private deleteCount = 0;
17
-
18
- /**
19
- * Track a Firestore operation
20
- */
21
- async trackOperation<T>(
22
- info: OperationInfo,
23
- operation: () => Promise<T>
24
- ): Promise<T> {
25
- try {
26
- return await operation();
27
- } finally {
28
- switch (info.type) {
29
- case 'read':
30
- if (!info.cached) {
31
- this.readCount += info.count;
32
- }
33
- break;
34
- case 'write':
35
- this.writeCount += info.count;
36
- break;
37
- case 'delete':
38
- this.deleteCount += info.count;
39
- break;
40
- }
41
- }
42
- }
43
-
44
- /**
45
- * Track read operation
46
- * @param _collection - Collection name (reserved for future per-collection tracking)
47
- * @param count - Number of documents read
48
- * @param cached - Whether result was from cache
49
- */
50
- trackRead(_collection: string, count: number = 1, cached: boolean = false): void {
51
- if (!cached) {
52
- this.readCount += count;
53
- }
54
- }
55
-
56
- /**
57
- * Track write operation
58
- * @param _collection - Collection name (reserved for future per-collection tracking)
59
- * @param count - Number of documents written
60
- */
61
- trackWrite(_collection: string, count: number = 1): void {
62
- this.writeCount += count;
63
- }
64
-
65
- /**
66
- * Track delete operation
67
- * @param _collection - Collection name (reserved for future per-collection tracking)
68
- * @param count - Number of documents deleted
69
- */
70
- trackDelete(_collection: string, count: number = 1): void {
71
- this.deleteCount += count;
72
- }
73
-
74
- /**
75
- * Get current counts
76
- */
77
- getCounts(): { reads: number; writes: number; deletes: number } {
78
- return {
79
- reads: this.readCount,
80
- writes: this.writeCount,
81
- deletes: this.deleteCount,
82
- };
83
- }
84
-
85
- /**
86
- * Reset counts
87
- */
88
- reset(): void {
89
- this.readCount = 0;
90
- this.writeCount = 0;
91
- this.deleteCount = 0;
92
- }
93
- }
94
-
95
- export const quotaTrackingMiddleware = new QuotaTrackingMiddleware();