@bts-soft/core 2.2.9 → 2.3.1

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 CHANGED
@@ -27,7 +27,7 @@ The ecosystem is built on three core pillars:
27
27
  | Package | Purpose | Key technologies |
28
28
  | :--- | :--- | :--- |
29
29
  | `@bts-soft/validation` | Domain-driven validation and security | Class-Validator, Class-Transformer |
30
- | `@bts-soft/cache` | Enterprise-grade Redis abstraction | ioredis, cache-manager |
30
+ | `@bts-soft/cache` | Enterprise-grade Redis abstraction | redis (v4), cache-manager |
31
31
  | `@bts-soft/notifications` | Reliable multi-channel delivery | BullMQ, Nodemailer, Twilio, FCM |
32
32
  | `@bts-soft/upload` | Media management and processing | Cloudinary, Strategy/Command Pattern |
33
33
  | `@bts-soft/common` | Infrastructure glue and standard bases | RXJS, TypeORM, Apollo |
@@ -219,152 +219,71 @@ The validation package also exports the underlying transformation functions for
219
219
 
220
220
  ## Deep Dive: `@bts-soft/cache`
221
221
 
222
- The caching module provides an enterprise-ready wrapper around Redis, designed to handle high-throughput operations with type safety and automatic serialization. It utilizes a **Modular Facade Pattern**, where the `RedisService` acts as a unified interface delegating to specialized internal services for different Redis data types (Hashes, Sets, Geospatial, etc.).
223
-
224
- ### The `IRedisInterface` Contract
225
-
226
- The `RedisService` implements the `IRedisInterface`, ensuring a consistent API surface across the entire application ecosystem.
227
-
228
- ---
229
-
230
- ### Core Key-Value Operations
231
-
232
- These are the most commonly used methods for simple state management.
233
-
234
- #### `set(key: string, value: any, ttl?: number): Promise<void>`
235
- Stores a value in Redis with automatic JSON stringification.
236
- - **TTL**: Default is 3600 seconds (1 hour).
237
- - **Example**:
238
- ```typescript
239
- await redisService.set('user:session:123', { id: 123, role: 'admin' }, 600);
240
- ```
241
-
242
- #### `get<T = any>(key: string): Promise<T | null>`
243
- Retrieves and parses a value from Redis.
244
- - **Generic Type Support**: Automatically casts the result to your interface.
245
- - **Example**:
246
- ```typescript
247
- const session = await redisService.get<UserSession>('user:session:123');
248
- ```
249
-
250
- #### `del(key: string): Promise<void>`
251
- Removes a key from the database.
252
-
253
- #### `mSet(data: Record<string, any>): Promise<void>`
254
- Sets multiple key-value pairs atomically using a Redis pipeline.
255
- - **Example**:
256
- ```typescript
257
- await redisService.mSet({
258
- 'config:theme': 'dark',
259
- 'config:lang': 'ar'
260
- });
261
- ```
262
-
263
- ---
264
-
265
- ### String & Atomic Operations
266
-
267
- Perfect for building counters, distributed sequences, and atomic flags.
268
-
269
- #### `incr(key: string): Promise<number>`
270
- Increments the numeric value of a key by 1.
271
- - **Use Case**: Page view counters, attempt limiters.
272
-
273
- #### `incrBy(key: string, increment: number): Promise<number>`
274
- Increments a value by a specific integer amount.
275
-
276
- #### `decr(key: string): Promise<number>`
277
- Decrements the value by 1.
278
-
279
- #### `getSet(key: string, value: any): Promise<string | null>`
280
- Atomically sets a new value and returns the old value.
281
- - **Use Case**: Atomic state transitions.
282
-
283
- #### `strlen(key: string): Promise<number>`
284
- Returns the byte length of the stored string.
222
+ The `@bts-soft/cache` module is a high-performance Redis infrastructure layer designed for enterprise NestJS applications. It utilizes a **Modular Facade Pattern** where the `RedisService` orchestrates 13 specialized internal services, providing a unified API for everything from simple caching to complex distributed coordination.
285
223
 
286
224
  ---
287
225
 
288
- ### Complex Data Structures
289
-
290
- #### 1. Hashes (Object-like Storage)
291
- Ideal for storing entities without serializing the entire object every time.
292
-
293
- - `hSet(key, field, value)`: Set a field in a hash.
294
- - `hGet(key, field)`: Get a specific field.
295
- - `hGetAll(key)`: Retrieve the entire object.
296
- - `hIncrBy(key, field, amount)`: Atomic increment of a field.
297
- - `hSetNX(key, field, value)`: Set only if field doesn't exist.
298
-
299
- #### 2. Sets (Unique Collections)
300
- Manage unique lists of IDs, tags, or permissions.
301
-
302
- - `sAdd(key, ...members)`: Add unique items.
303
- - `sMembers(key)`: Get all unique items.
304
- - `sIsMember(key, member)`: Check membership.
305
- - `sInter(key1, key2)`: Find common items between sets.
306
- - `sUnion(key1, key2)`: Merge sets uniquely.
307
-
308
- #### 3. Sorted Sets (Scored Rankings)
309
- The ultimate tool for leaderboards, activity feeds, and priority queues.
226
+ ### Key Capabilities
310
227
 
311
- - `zAdd(key, score, member)`: Add item with a specific numeric score.
312
- - `zRange(key, start, stop)`: Get members by index (Sorted by score).
313
- - `zRank(key, member)`: Get the position of a member in the list.
314
- - `zRemRangeByScore(key, min, max)`: Cleanup old or low-score data.
315
-
316
- #### 4. Lists (Linear Order)
317
- - `lPush(key, value)`: Prepend to list.
318
- - `rPop(key)`: Remove and return the last item (Queue logic).
319
- - `lTrim(key, start, stop)`: Maintain a fixed-size history (Capping).
228
+ 1. **Atomic Distributed Locking**: Prevents race conditions in distributed environments using `acquireLock` and `waitForLock`.
229
+ 2. **Reliable Pub/Sub**: High-speed, multi-channel event distribution with dedicated subscriber connections to ensure non-blocking operations.
230
+ 3. **Complex Data Structures**: Native support for Hashes, Sets, Sorted Sets (Rankings), and Lists.
231
+ 4. **Advanced Analytics**: Geospatial indexing for "nearby" features and HyperLogLog for memory-efficient unique counting.
232
+ 5. **100% Verified Infrastructure**: Every operation is backed by comprehensive E2E tests running on real Redis instances.
320
233
 
321
234
  ---
322
235
 
323
- ### Advanced Data Types
324
-
325
- #### Geospatial Indexing
326
- Build "Nearby" features (Find stores, users, or assets).
327
- - `geoAdd(key, long, lat, member)`: Index a coordinate.
328
- - `geoDist(member1, member2, unit)`: Calculate distance between two points.
329
- - `geoPos(key, member)`: Get coordinates for a member.
330
-
331
- #### HyperLogLog (Probabilistic Counting)
332
- Count unique items across millions of entries with minimal memory (approx 12KB).
333
- - `pfAdd(key, ...elements)`: Observe an element.
334
- - `pfCount(key)`: Get approximate unique count.
236
+ ### Core Operations API
335
237
 
336
- ---
337
-
338
- ### Distributed Locking & Messaging
238
+ #### 1. Standard Caching
239
+ - `set(key, value, ttl?)`: Stores values with automatic JSON serialization (Default TTL: 1 hour).
240
+ - `setForever(key, value)`: Bypasses default TTLs for permanent configuration or state storage.
241
+ - `get<T>(key)`: Retrieves and automatically parses JSON into typed objects.
242
+ - `del(key)`: Removes keys from the database.
339
243
 
340
- #### Distributed Locking
341
- The `RedisService` includes a high-level lock implementation to prevent race conditions in distributed systems.
244
+ #### 2. Atomic Numeric Operations
245
+ - `incr(key)` / `decr(key)`: Atomically increments or decrements integers.
246
+ - `incrByFloat(key, n)`: Handles precise floating-point increments.
342
247
 
248
+ #### 3. Distributed Locking Example
343
249
  ```typescript
344
- const lockValue = await redisService.acquireLock('process:order:789', 'worker-1', 5000);
345
- if (lockValue) {
250
+ const lockValue = crypto.randomUUID();
251
+ const acquired = await redisService.acquireLock('order:process:123', lockValue, 5000);
252
+
253
+ if (acquired) {
346
254
  try {
347
- // Perform sensitive operation
255
+ // Critical section logic
348
256
  } finally {
349
- await redisService.releaseLock('process:order:789', lockValue);
257
+ await redisService.releaseLock('order:process:123', lockValue);
350
258
  }
351
259
  }
352
260
  ```
353
261
 
354
- #### Pub/Sub Messaging
355
- Enable real-time communication between microservices.
262
+ #### 4. Real-time Pub/Sub Example
356
263
  ```typescript
357
- // Subscriber
358
- await redisService.subscribe('events:new-user', (msg) => {
359
- console.log('New user joined:', JSON.parse(msg));
264
+ // Subscriber (Dedicated connection handled automatically)
265
+ await redisService.subscribe('system_updates', (msg) => {
266
+ console.log('Update received:', JSON.parse(msg));
360
267
  });
361
268
 
362
269
  // Publisher
363
- await redisService.publish('events:new-user', { id: 1, name: 'Omar' });
270
+ await redisService.publish('system_updates', { status: 'OK', timestamp: Date.now() });
364
271
  ```
365
272
 
366
273
  ---
367
274
 
275
+ ### Data Structure Reference
276
+
277
+ | Structure | Common Methods | Best For |
278
+ | :--- | :--- | :--- |
279
+ | **Hashes** | `hSet`, `hGetAll`, `hIncrBy` | Object storage, User profiles |
280
+ | **Sorted Sets** | `zAdd`, `zRange`, `zScore` | Leaderboards, Scored feeds |
281
+ | **Sets** | `sAdd`, `sMembers`, `sIsMember` | Unique tags, Permissions |
282
+ | **Lists** | `lPush`, `rPop`, `lTrim` | Queues, Activity history |
283
+ | **Geo** | `geoAdd`, `geoDist`, `geoPos` | Nearby stores, Proximity search |
284
+
285
+ ---
286
+
368
287
  ## Deep Dive: `@bts-soft/notifications`
369
288
 
370
289
  The notification module is a high-availability delivery engine designed to handle massive volumes of transactional and marketing messages across multiple protocols without slowing down your primary application.
@@ -3154,7 +3073,7 @@ When deploying @bts-soft/core in the Middle East & North Africa (MENA), specific
3154
3073
  - **Reasoning**: Intra-GCC fiber is fast, but cross-cloud peering can be jittery.
3155
3074
 
3156
3075
  ### Network Profile 2: High-Durability SMTP (North Africa)
3157
- - **Primary Host**: Cairo
3076
+ - **Primary Host**: Damietta
3158
3077
  - **Gateway**: SendGrid (Relay via London)
3159
3078
  - **Tuning Strategy**:
3160
3079
  - dns_lookup: Prefer IPv4 (Avoid IPv6 propagation lag).