@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 +42 -123
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
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 |
|
|
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
|
|
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
|
-
###
|
|
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
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
####
|
|
341
|
-
|
|
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 =
|
|
345
|
-
|
|
250
|
+
const lockValue = crypto.randomUUID();
|
|
251
|
+
const acquired = await redisService.acquireLock('order:process:123', lockValue, 5000);
|
|
252
|
+
|
|
253
|
+
if (acquired) {
|
|
346
254
|
try {
|
|
347
|
-
//
|
|
255
|
+
// Critical section logic
|
|
348
256
|
} finally {
|
|
349
|
-
await redisService.releaseLock('process:
|
|
257
|
+
await redisService.releaseLock('order:process:123', lockValue);
|
|
350
258
|
}
|
|
351
259
|
}
|
|
352
260
|
```
|
|
353
261
|
|
|
354
|
-
#### Pub/Sub
|
|
355
|
-
Enable real-time communication between microservices.
|
|
262
|
+
#### 4. Real-time Pub/Sub Example
|
|
356
263
|
```typescript
|
|
357
|
-
// Subscriber
|
|
358
|
-
await redisService.subscribe('
|
|
359
|
-
console.log('
|
|
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('
|
|
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**:
|
|
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).
|