@wgtechlabs/nuvex 0.1.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/LICENSE +21 -0
- package/README.md +427 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/cjs/core/client.js +981 -0
- package/dist/cjs/core/client.js.map +1 -0
- package/dist/cjs/core/database.js +297 -0
- package/dist/cjs/core/database.js.map +1 -0
- package/dist/cjs/core/engine.js +1202 -0
- package/dist/cjs/core/engine.js.map +1 -0
- package/dist/cjs/core/index.js +35 -0
- package/dist/cjs/core/index.js.map +1 -0
- package/dist/cjs/index.js +109 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/interfaces/index.js +12 -0
- package/dist/cjs/interfaces/index.js.map +1 -0
- package/dist/cjs/layers/index.js +22 -0
- package/dist/cjs/layers/index.js.map +1 -0
- package/dist/cjs/layers/memory.js +388 -0
- package/dist/cjs/layers/memory.js.map +1 -0
- package/dist/cjs/layers/postgres.js +492 -0
- package/dist/cjs/layers/postgres.js.map +1 -0
- package/dist/cjs/layers/redis.js +388 -0
- package/dist/cjs/layers/redis.js.map +1 -0
- package/dist/cjs/types/index.js +52 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/esm/core/client.js +944 -0
- package/dist/esm/core/client.js.map +1 -0
- package/dist/esm/core/database.js +289 -0
- package/dist/esm/core/database.js.map +1 -0
- package/dist/esm/core/engine.js +1198 -0
- package/dist/esm/core/engine.js.map +1 -0
- package/dist/esm/core/index.js +16 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/index.js +87 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/interfaces/index.js +11 -0
- package/dist/esm/interfaces/index.js.map +1 -0
- package/dist/esm/layers/index.js +16 -0
- package/dist/esm/layers/index.js.map +1 -0
- package/dist/esm/layers/memory.js +384 -0
- package/dist/esm/layers/memory.js.map +1 -0
- package/dist/esm/layers/postgres.js +485 -0
- package/dist/esm/layers/postgres.js.map +1 -0
- package/dist/esm/layers/redis.js +384 -0
- package/dist/esm/layers/redis.js.map +1 -0
- package/dist/esm/types/index.js +49 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/types/core/client.d.ts +561 -0
- package/dist/types/core/client.d.ts.map +1 -0
- package/dist/types/core/database.d.ts +130 -0
- package/dist/types/core/database.d.ts.map +1 -0
- package/dist/types/core/engine.d.ts +450 -0
- package/dist/types/core/engine.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +13 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +85 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/interfaces/index.d.ts +209 -0
- package/dist/types/interfaces/index.d.ts.map +1 -0
- package/dist/types/layers/index.d.ts +16 -0
- package/dist/types/layers/index.d.ts.map +1 -0
- package/dist/types/layers/memory.d.ts +261 -0
- package/dist/types/layers/memory.d.ts.map +1 -0
- package/dist/types/layers/postgres.d.ts +313 -0
- package/dist/types/layers/postgres.d.ts.map +1 -0
- package/dist/types/layers/redis.d.ts +248 -0
- package/dist/types/layers/redis.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +410 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/core/database.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAYrD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAM5E;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,oBAAoB,GAAG,MAAM,CA+D5E;AAED,eAAO,MAAM,gBAAgB,QAA2B,CAAC;AAEzD,MAAM,WAAW,kBAAkB;IACjC,gFAAgF;IAChF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yDAAyD;IACzD,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,QAAQ,EACZ,OAAO,GAAE,kBAAuB,EAChC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAwBf;AAiDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,qBAAqB,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAYzH;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBjH"}
|
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nuvex - Storage Engine
|
|
3
|
+
* Next-gen Unified Vault Experience
|
|
4
|
+
*
|
|
5
|
+
* Multi-layer storage architecture that provides intelligent caching and data
|
|
6
|
+
* persistence for any Node.js application. Implements a three-tier storage system
|
|
7
|
+
* optimized for performance, scalability, and reliability.
|
|
8
|
+
*
|
|
9
|
+
* Storage Architecture:
|
|
10
|
+
* - Layer 1: Memory Cache (configurable TTL) - Fastest access for hot data
|
|
11
|
+
* - Layer 2: Redis Cache (configurable TTL) - Fast distributed cache for warm data
|
|
12
|
+
* - Layer 3: PostgreSQL (Permanent) - Persistent storage for cold data
|
|
13
|
+
*
|
|
14
|
+
* Key Features:
|
|
15
|
+
* - Automatic data tier management and promotion/demotion
|
|
16
|
+
* - Configurable TTL (Time To Live) for each storage layer
|
|
17
|
+
* - Intelligent fallback mechanism between storage tiers
|
|
18
|
+
* - Memory cleanup and garbage collection
|
|
19
|
+
* - Connection pooling and error recovery
|
|
20
|
+
* - Pluggable logging support
|
|
21
|
+
*
|
|
22
|
+
* @author Waren Gonzaga, WG Technology Labs
|
|
23
|
+
* @since 2025
|
|
24
|
+
*/
|
|
25
|
+
import type { NuvexConfig, StorageOptions, BatchOperation, BatchResult, QueryOptions, QueryResult } from '../types/index.js';
|
|
26
|
+
import type { Storage } from '../interfaces/index.js';
|
|
27
|
+
/**
|
|
28
|
+
* # StorageEngine - Multi-layer Storage Architecture
|
|
29
|
+
*
|
|
30
|
+
* The core storage engine that implements Nuvex's intelligent three-tier storage system.
|
|
31
|
+
* Provides automatic data management, intelligent caching, and comprehensive fallback mechanisms
|
|
32
|
+
* across Memory, Redis, and PostgreSQL layers.
|
|
33
|
+
*
|
|
34
|
+
* ## Architecture Design
|
|
35
|
+
*
|
|
36
|
+
* The StorageEngine follows a hierarchical approach where data flows through layers based on
|
|
37
|
+
* access patterns and configured policies:
|
|
38
|
+
*
|
|
39
|
+
* ```
|
|
40
|
+
* ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
41
|
+
* │ Memory │───▶│ Redis │───▶│ PostgreSQL │
|
|
42
|
+
* │ (Layer 1) │ │ (Layer 2) │ │ (Layer 3) │
|
|
43
|
+
* │ < 1ms │ │ 1-5ms │ │ 5-50ms │
|
|
44
|
+
* └─────────────┘ └─────────────┘ └─────────────┘
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* ## Key Features
|
|
48
|
+
*
|
|
49
|
+
* ### Intelligent Data Management
|
|
50
|
+
* - **Automatic Promotion**: Frequently accessed data moves to faster layers
|
|
51
|
+
* - **Smart Demotion**: Unused data gracefully moves to persistent storage
|
|
52
|
+
* - **TTL Management**: Configurable time-to-live for each layer
|
|
53
|
+
* - **Memory Optimization**: LRU eviction and automatic cleanup
|
|
54
|
+
*
|
|
55
|
+
* ### Performance Optimization
|
|
56
|
+
* - **Sub-millisecond Access**: Memory cache for hot data
|
|
57
|
+
* - **Batch Operations**: Efficient bulk data operations
|
|
58
|
+
* - **Connection Pooling**: Optimized database connections
|
|
59
|
+
* - **Metrics Collection**: Real-time performance monitoring
|
|
60
|
+
*
|
|
61
|
+
* ### Reliability Features
|
|
62
|
+
* - **Graceful Degradation**: Automatic fallback when layers are unavailable
|
|
63
|
+
* - **Error Recovery**: Comprehensive error handling and logging
|
|
64
|
+
* - **Data Consistency**: Synchronization across all storage layers
|
|
65
|
+
* - **Health Monitoring**: Layer availability and performance tracking
|
|
66
|
+
*
|
|
67
|
+
* ## Usage Examples
|
|
68
|
+
*
|
|
69
|
+
* ### Basic Operations
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const engine = new StorageEngine({
|
|
72
|
+
* memory: { ttl: 3600000, maxSize: 10000 },
|
|
73
|
+
* redis: { url: 'redis://localhost:6379' },
|
|
74
|
+
* postgres: { host: 'localhost', database: 'app' }
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* await engine.connect();
|
|
78
|
+
*
|
|
79
|
+
* // Set data across all layers
|
|
80
|
+
* await engine.set('user:123', userData);
|
|
81
|
+
*
|
|
82
|
+
* // Get data (checks Memory → Redis → PostgreSQL)
|
|
83
|
+
* const user = await engine.get('user:123');
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* ### Layer-specific Operations
|
|
87
|
+
* ```typescript
|
|
88
|
+
* // Store only in Redis
|
|
89
|
+
* await engine.set('session:abc', sessionData, {
|
|
90
|
+
* layer: StorageLayer.REDIS
|
|
91
|
+
* });
|
|
92
|
+
*
|
|
93
|
+
* // Skip cache and go directly to PostgreSQL
|
|
94
|
+
* const criticalData = await engine.get('config:critical', {
|
|
95
|
+
* skipCache: true
|
|
96
|
+
* });
|
|
97
|
+
* ```
|
|
98
|
+
*
|
|
99
|
+
* ### Batch Operations
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const operations = [
|
|
102
|
+
* { operation: 'set', key: 'key1', value: 'value1' },
|
|
103
|
+
* { operation: 'set', key: 'key2', value: 'value2' }
|
|
104
|
+
* ];
|
|
105
|
+
*
|
|
106
|
+
* const results = await engine.setBatch(operations);
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* // Initialize with full configuration
|
|
112
|
+
* const engine = new StorageEngine({
|
|
113
|
+
* memory: {
|
|
114
|
+
* ttl: 24 * 60 * 60 * 1000, // 24 hours
|
|
115
|
+
* maxSize: 10000
|
|
116
|
+
* },
|
|
117
|
+
* redis: {
|
|
118
|
+
* url: 'redis://localhost:6379',
|
|
119
|
+
* ttl: 3 * 24 * 60 * 60 // 3 days
|
|
120
|
+
* },
|
|
121
|
+
* postgres: {
|
|
122
|
+
* host: 'localhost',
|
|
123
|
+
* port: 5432,
|
|
124
|
+
* database: 'myapp',
|
|
125
|
+
* user: 'user',
|
|
126
|
+
* password: 'password'
|
|
127
|
+
* },
|
|
128
|
+
* logging: {
|
|
129
|
+
* enabled: true,
|
|
130
|
+
* logger: console
|
|
131
|
+
* }
|
|
132
|
+
* });
|
|
133
|
+
*
|
|
134
|
+
* await engine.connect();
|
|
135
|
+
*
|
|
136
|
+
* // Your storage operations here...
|
|
137
|
+
*
|
|
138
|
+
* await engine.disconnect();
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* @see {@link NuvexClient} for high-level client operations
|
|
142
|
+
* @see {@link NuvexConfig} for configuration options
|
|
143
|
+
* @see {@link StorageOptions} for operation-specific options
|
|
144
|
+
*
|
|
145
|
+
* @public
|
|
146
|
+
* @category Core
|
|
147
|
+
*/
|
|
148
|
+
export declare class StorageEngine implements Storage {
|
|
149
|
+
private l1Memory;
|
|
150
|
+
private l2Redis;
|
|
151
|
+
private l3Postgres;
|
|
152
|
+
private config;
|
|
153
|
+
private connected;
|
|
154
|
+
private cleanupInterval;
|
|
155
|
+
private logger;
|
|
156
|
+
private metrics;
|
|
157
|
+
/**
|
|
158
|
+
* Creates a new StorageEngine instance with the specified configuration.
|
|
159
|
+
*
|
|
160
|
+
* The constructor initializes all three storage layers and sets up automatic
|
|
161
|
+
* memory cleanup intervals. No connections are established until `connect()` is called.
|
|
162
|
+
*
|
|
163
|
+
* @param config - Complete configuration object for all storage layers
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* const engine = new StorageEngine({
|
|
168
|
+
* memory: { ttl: 3600000, maxSize: 10000 },
|
|
169
|
+
* redis: { url: 'redis://localhost:6379', ttl: 86400 },
|
|
170
|
+
* postgres: { host: 'localhost', database: 'myapp' },
|
|
171
|
+
* logging: { enabled: true }
|
|
172
|
+
* });
|
|
173
|
+
* ```
|
|
174
|
+
*
|
|
175
|
+
* @throws {Error} When configuration is invalid
|
|
176
|
+
* @since 1.0.0
|
|
177
|
+
*/
|
|
178
|
+
constructor(config: NuvexConfig);
|
|
179
|
+
private log;
|
|
180
|
+
/**
|
|
181
|
+
* Establishes connections to all configured storage layers.
|
|
182
|
+
*
|
|
183
|
+
* This method initializes connections to Redis and PostgreSQL (if configured)
|
|
184
|
+
* and sets up the internal state for multi-layer operations. The memory layer
|
|
185
|
+
* is always available and doesn't require connection setup.
|
|
186
|
+
*
|
|
187
|
+
* @throws {Error} When connection to any configured layer fails
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```typescript
|
|
191
|
+
* const engine = new StorageEngine(config);
|
|
192
|
+
* await engine.connect();
|
|
193
|
+
* console.log('All storage layers connected');
|
|
194
|
+
* ```
|
|
195
|
+
*
|
|
196
|
+
* @since 1.0.0
|
|
197
|
+
* @public
|
|
198
|
+
*/
|
|
199
|
+
connect(): Promise<void>;
|
|
200
|
+
disconnect(): Promise<void>;
|
|
201
|
+
isConnected(): boolean;
|
|
202
|
+
/**
|
|
203
|
+
* Retrieves a value from storage using the intelligent layer hierarchy.
|
|
204
|
+
*
|
|
205
|
+
* The get operation follows the multi-layer approach:
|
|
206
|
+
* 1. **Memory Cache**: Checks in-memory storage first (fastest)
|
|
207
|
+
* 2. **Redis Cache**: Falls back to Redis if not in memory
|
|
208
|
+
* 3. **PostgreSQL**: Final fallback to persistent storage
|
|
209
|
+
*
|
|
210
|
+
* When data is found in a lower layer, it's automatically promoted to higher
|
|
211
|
+
* layers for faster future access (intelligent caching).
|
|
212
|
+
*
|
|
213
|
+
* @template T - The expected type of the stored value
|
|
214
|
+
* @param key - The storage key to retrieve
|
|
215
|
+
* @param options - Optional configuration for the get operation
|
|
216
|
+
* @returns Promise resolving to the stored value or null if not found
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```typescript
|
|
220
|
+
* // Basic get operation
|
|
221
|
+
* const userData = await engine.get<UserData>('user:123');
|
|
222
|
+
*
|
|
223
|
+
* // Get from specific layer only
|
|
224
|
+
* const sessionData = await engine.get('session:abc', {
|
|
225
|
+
* layer: StorageLayer.REDIS
|
|
226
|
+
* });
|
|
227
|
+
*
|
|
228
|
+
* // Skip cache layers and get from PostgreSQL directly
|
|
229
|
+
* const criticalData = await engine.get('config:critical', {
|
|
230
|
+
* skipCache: true
|
|
231
|
+
* });
|
|
232
|
+
* ```
|
|
233
|
+
*
|
|
234
|
+
* @since 1.0.0
|
|
235
|
+
* @public
|
|
236
|
+
*/
|
|
237
|
+
get<T = unknown>(key: string, options?: StorageOptions): Promise<T | null>;
|
|
238
|
+
/**
|
|
239
|
+
* Set value in storage layers using L3-first write strategy
|
|
240
|
+
*
|
|
241
|
+
* **L3-First Write Strategy:**
|
|
242
|
+
* 1. Write to PostgreSQL (L3) first as source of truth
|
|
243
|
+
* 2. If L3 write succeeds, warm caches (L1, L2) using Promise.allSettled
|
|
244
|
+
* 3. Cache failures don't break the operation (graceful degradation)
|
|
245
|
+
*
|
|
246
|
+
* **Error Handling:**
|
|
247
|
+
* - Returns `false` if L3 (PostgreSQL) write fails - operation is aborted
|
|
248
|
+
* - Returns `false` if engine is not connected
|
|
249
|
+
* - Returns `true` if L3 write succeeds (cache failures are tolerated)
|
|
250
|
+
* - For memory/Redis-only deployments (no L3), cache write success determines result
|
|
251
|
+
*
|
|
252
|
+
* **Usage Recommendations:**
|
|
253
|
+
* ```typescript
|
|
254
|
+
* // Always check the return value for critical data
|
|
255
|
+
* const success = await engine.set('user:123', userData);
|
|
256
|
+
* if (!success) {
|
|
257
|
+
* // Handle failure: retry, log, alert, or use fallback
|
|
258
|
+
* console.error('Failed to persist user data');
|
|
259
|
+
* throw new Error('Storage operation failed');
|
|
260
|
+
* }
|
|
261
|
+
*
|
|
262
|
+
* // For non-critical data, you may proceed regardless
|
|
263
|
+
* await engine.set('cache:temp', tempData); // Fire and forget
|
|
264
|
+
* ```
|
|
265
|
+
*
|
|
266
|
+
* @param key - The key to store
|
|
267
|
+
* @param value - The value to store
|
|
268
|
+
* @param options - Optional storage options (ttl, layer targeting)
|
|
269
|
+
* @returns Promise resolving to true if operation succeeded, false otherwise
|
|
270
|
+
*/
|
|
271
|
+
set<T = unknown>(key: string, value: T, options?: StorageOptions): Promise<boolean>;
|
|
272
|
+
/**
|
|
273
|
+
* Delete from all storage layers using resilient approach
|
|
274
|
+
*
|
|
275
|
+
* Uses Promise.allSettled to attempt deletion from all layers without
|
|
276
|
+
* failing if individual layers are unavailable. This provides graceful
|
|
277
|
+
* degradation - even if cache layers fail, the operation continues.
|
|
278
|
+
*
|
|
279
|
+
* @param key - The key to delete
|
|
280
|
+
* @param options - Optional storage options (layer targeting)
|
|
281
|
+
* @returns Promise resolving to true if operation completed
|
|
282
|
+
*/
|
|
283
|
+
delete(key: string, options?: StorageOptions): Promise<boolean>;
|
|
284
|
+
/**
|
|
285
|
+
* Check if key exists in any storage layer
|
|
286
|
+
*/
|
|
287
|
+
exists(key: string, options?: StorageOptions): Promise<boolean>;
|
|
288
|
+
/**
|
|
289
|
+
* Set expiration for a key
|
|
290
|
+
*
|
|
291
|
+
* Note: This is a simplified implementation that re-sets the value with new TTL.
|
|
292
|
+
* For a more efficient implementation, layers would need an expire() method.
|
|
293
|
+
*/
|
|
294
|
+
expire(key: string, ttl: number): Promise<boolean>;
|
|
295
|
+
/**
|
|
296
|
+
* Atomically increment a numeric value
|
|
297
|
+
*
|
|
298
|
+
* This method uses layer-specific atomic operations when available,
|
|
299
|
+
* providing thread-safe increments across all storage layers.
|
|
300
|
+
*
|
|
301
|
+
* **Important:** The key must contain a numeric value (or not exist).
|
|
302
|
+
* If the key contains a non-numeric value, the operation will fail:
|
|
303
|
+
* - Redis: Throws error "value is not an integer"
|
|
304
|
+
* - PostgreSQL: Throws error during numeric cast
|
|
305
|
+
* - Memory: Treats non-numeric values as 0
|
|
306
|
+
*
|
|
307
|
+
* The increment cascades through layers:
|
|
308
|
+
* 1. If L3 (PostgreSQL) is available, use its atomic UPSERT
|
|
309
|
+
* 2. Else if L2 (Redis) is available, use INCRBY
|
|
310
|
+
* 3. Else use L1 (Memory) increment
|
|
311
|
+
*
|
|
312
|
+
* After incrementing in the authoritative layer, the new value is
|
|
313
|
+
* propagated to higher layers for cache consistency.
|
|
314
|
+
*
|
|
315
|
+
* @param key - The key to increment (must contain numeric value or not exist)
|
|
316
|
+
* @param delta - The amount to increment by (default: 1)
|
|
317
|
+
* @param ttl - Optional TTL in milliseconds
|
|
318
|
+
* @returns Promise resolving to the new value after increment
|
|
319
|
+
* @throws {Error} If the key contains a non-numeric value (Redis/PostgreSQL)
|
|
320
|
+
* @throws {Error} If no storage layer is available
|
|
321
|
+
*
|
|
322
|
+
* @example
|
|
323
|
+
* ```typescript
|
|
324
|
+
* // Increment counter by 1
|
|
325
|
+
* const newValue = await engine.increment('page_views');
|
|
326
|
+
*
|
|
327
|
+
* // Increment with custom delta
|
|
328
|
+
* const credits = await engine.increment('user:credits', 10);
|
|
329
|
+
*
|
|
330
|
+
* // Decrement (negative delta)
|
|
331
|
+
* const remaining = await engine.increment('inventory', -1);
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
increment(key: string, delta?: number, ttl?: number): Promise<number>;
|
|
335
|
+
setBatch(operations: BatchOperation[]): Promise<BatchResult[]>;
|
|
336
|
+
getBatch(keys: string[], options?: StorageOptions): Promise<BatchResult[]>;
|
|
337
|
+
deleteBatch(keys: string[]): Promise<BatchResult[]>;
|
|
338
|
+
query<T = unknown>(options: QueryOptions): Promise<QueryResult<T>>;
|
|
339
|
+
/**
|
|
340
|
+
* Get all keys matching a pattern across all storage layers
|
|
341
|
+
*
|
|
342
|
+
* Collects keys from all available layers (Memory, Redis, PostgreSQL) and
|
|
343
|
+
* returns deduplicated results. Currently implemented for the Memory layer;
|
|
344
|
+
* Redis and PostgreSQL layer support will be added in future versions.
|
|
345
|
+
*
|
|
346
|
+
* @param pattern - Glob pattern for key matching (default: '*' returns all keys)
|
|
347
|
+
* @returns Promise resolving to array of unique matching keys
|
|
348
|
+
*
|
|
349
|
+
* @since 1.0.0
|
|
350
|
+
*/
|
|
351
|
+
keys(pattern?: string): Promise<string[]>;
|
|
352
|
+
clear(pattern?: string): Promise<number>;
|
|
353
|
+
/**
|
|
354
|
+
* Get performance metrics for all layers or specific layer(s)
|
|
355
|
+
*
|
|
356
|
+
* Returns metrics about storage operations and performance. Can be filtered
|
|
357
|
+
* to return metrics for specific layers only.
|
|
358
|
+
*
|
|
359
|
+
* **Metrics by Layer:**
|
|
360
|
+
* - Memory: memoryHits, memoryMisses, memorySize, memoryMaxSize
|
|
361
|
+
* - Redis: redisHits, redisMisses
|
|
362
|
+
* - PostgreSQL: postgresHits, postgresMisses
|
|
363
|
+
* - Overall: totalOperations, cacheHitRatio, averageResponseTime
|
|
364
|
+
*
|
|
365
|
+
* @param layers - Optional layer(s) to get metrics for. If not provided, returns all metrics.
|
|
366
|
+
* Can be a single layer string, 'all', or array of layer strings.
|
|
367
|
+
* @returns Object containing requested metrics
|
|
368
|
+
*
|
|
369
|
+
* @example
|
|
370
|
+
* ```typescript
|
|
371
|
+
* // Get all metrics
|
|
372
|
+
* const metrics = engine.getMetrics();
|
|
373
|
+
* // { memoryHits, memoryMisses, redisHits, redisMisses, postgresHits, ... }
|
|
374
|
+
*
|
|
375
|
+
* // Get specific layer metrics
|
|
376
|
+
* const memoryMetrics = engine.getMetrics('memory');
|
|
377
|
+
* // { memoryHits, memoryMisses, memorySize, memoryMaxSize }
|
|
378
|
+
*
|
|
379
|
+
* // Get multiple layer metrics
|
|
380
|
+
* const cacheMetrics = engine.getMetrics(['memory', 'redis']);
|
|
381
|
+
* // { memoryHits, memoryMisses, memorySize, memoryMaxSize, redisHits, redisMisses, totalOperations, averageResponseTime, cacheHitRatio }
|
|
382
|
+
* ```
|
|
383
|
+
*
|
|
384
|
+
* @since 1.0.0
|
|
385
|
+
* @public
|
|
386
|
+
*/
|
|
387
|
+
getMetrics(layers?: 'memory' | 'redis' | 'postgres' | 'all' | Array<'memory' | 'redis' | 'postgres'>): Record<string, number>;
|
|
388
|
+
resetMetrics(): void;
|
|
389
|
+
/**
|
|
390
|
+
* Perform health check on all storage layers or specific layer(s)
|
|
391
|
+
*
|
|
392
|
+
* Uses Promise.allSettled to check all layers independently without
|
|
393
|
+
* failing if one layer is down. Each layer's ping() method is called
|
|
394
|
+
* to verify its operational status.
|
|
395
|
+
*
|
|
396
|
+
* **Layer Health Checks:**
|
|
397
|
+
* - Memory (L1): Always healthy if app is running
|
|
398
|
+
* - Redis (L2): PING command verification
|
|
399
|
+
* - PostgreSQL (L3): SELECT 1 query verification
|
|
400
|
+
*
|
|
401
|
+
* @param layers - Optional layer(s) to check. If not provided, checks all layers.
|
|
402
|
+
* Can be a single layer string or array of layer strings.
|
|
403
|
+
* @returns Promise resolving to health status of requested layer(s)
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* ```typescript
|
|
407
|
+
* // Check all layers
|
|
408
|
+
* const health = await engine.healthCheck();
|
|
409
|
+
* // { memory: true, redis: true, postgres: true }
|
|
410
|
+
*
|
|
411
|
+
* // Check specific layer
|
|
412
|
+
* const redisHealth = await engine.healthCheck('redis');
|
|
413
|
+
* // { redis: true }
|
|
414
|
+
*
|
|
415
|
+
* // Check multiple specific layers
|
|
416
|
+
* const cacheHealth = await engine.healthCheck(['memory', 'redis']);
|
|
417
|
+
* // { memory: true, redis: true }
|
|
418
|
+
*
|
|
419
|
+
* if (!health.redis) {
|
|
420
|
+
* console.warn('Redis layer is down, degraded performance expected');
|
|
421
|
+
* }
|
|
422
|
+
* ```
|
|
423
|
+
*
|
|
424
|
+
* @since 1.0.0
|
|
425
|
+
* @public
|
|
426
|
+
*/
|
|
427
|
+
healthCheck(layers?: 'memory' | 'redis' | 'postgres' | Array<'memory' | 'redis' | 'postgres'>): Promise<Record<string, boolean>>;
|
|
428
|
+
promote(key: string, targetLayer: string): Promise<boolean>;
|
|
429
|
+
demote(key: string, targetLayer: string): Promise<boolean>;
|
|
430
|
+
getLayerInfo(key: string): Promise<{
|
|
431
|
+
layer: string;
|
|
432
|
+
ttl?: number;
|
|
433
|
+
} | null>;
|
|
434
|
+
private startMemoryCleanup;
|
|
435
|
+
private updateResponseTime;
|
|
436
|
+
private calculateCacheHitRatio;
|
|
437
|
+
private applySorting;
|
|
438
|
+
private applyPagination;
|
|
439
|
+
getStats(): {
|
|
440
|
+
memoryKeys: number;
|
|
441
|
+
connected: boolean;
|
|
442
|
+
layers: {
|
|
443
|
+
memory: boolean;
|
|
444
|
+
redis: boolean;
|
|
445
|
+
postgres: boolean;
|
|
446
|
+
};
|
|
447
|
+
};
|
|
448
|
+
cleanupExpiredMemory(): Promise<number>;
|
|
449
|
+
}
|
|
450
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/core/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nuvex - Core Module Exports
|
|
3
|
+
* Next-gen Unified Vault Experience
|
|
4
|
+
*
|
|
5
|
+
* Clean exports for all core components
|
|
6
|
+
*
|
|
7
|
+
* @author Waren Gonzaga, WG Technology Labs
|
|
8
|
+
* @since 2025
|
|
9
|
+
*/
|
|
10
|
+
export { StorageEngine } from './engine.js';
|
|
11
|
+
export { NuvexClient } from './client.js';
|
|
12
|
+
export * from './database.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # Nuvex - Next-gen Unified Vault Experience
|
|
3
|
+
*
|
|
4
|
+
* A production-ready, minimalist SDK for structured memory layering in Redis and PostgreSQL.
|
|
5
|
+
* Designed for any Node.js application that needs intelligent multi-layer storage with automatic
|
|
6
|
+
* data promotion, demotion, and comprehensive reliability features.
|
|
7
|
+
*
|
|
8
|
+
* ## Architecture Overview
|
|
9
|
+
*
|
|
10
|
+
* Nuvex implements a sophisticated three-tier storage system:
|
|
11
|
+
*
|
|
12
|
+
* ### Layer 1: Memory Cache (Ultra-fast)
|
|
13
|
+
* - **TTL**: Configurable (default: 24 hours)
|
|
14
|
+
* - **Use case**: Hot data, session information, frequently accessed content
|
|
15
|
+
* - **Performance**: Sub-millisecond access time
|
|
16
|
+
* - **Features**: LRU eviction, automatic cleanup, size limits
|
|
17
|
+
*
|
|
18
|
+
* ### Layer 2: Redis Cache (Fast & Distributed)
|
|
19
|
+
* - **TTL**: Configurable (default: 3 days)
|
|
20
|
+
* - **Use case**: Warm data, distributed caching across instances
|
|
21
|
+
* - **Performance**: 1-5ms access time
|
|
22
|
+
* - **Features**: Atomic operations, cluster support, persistence
|
|
23
|
+
*
|
|
24
|
+
* ### Layer 3: PostgreSQL (Persistent & Reliable)
|
|
25
|
+
* - **TTL**: Permanent storage with optional expiration
|
|
26
|
+
* - **Use case**: Cold data, critical information, audit trails
|
|
27
|
+
* - **Performance**: 5-50ms access time depending on query complexity
|
|
28
|
+
* - **Features**: ACID compliance, advanced querying, schema flexibility
|
|
29
|
+
*
|
|
30
|
+
* ## Key Components
|
|
31
|
+
*
|
|
32
|
+
* - **{@link StorageEngine}**: Low-level multi-layer storage implementation
|
|
33
|
+
* - **{@link NuvexClient}**: High-level client with convenience methods
|
|
34
|
+
* - **Database Utilities**: Schema management and migration tools
|
|
35
|
+
* - **Type System**: Comprehensive TypeScript definitions
|
|
36
|
+
*
|
|
37
|
+
* ## Quick Start Example
|
|
38
|
+
*
|
|
39
|
+
* ```typescript
|
|
40
|
+
* import { NuvexClient } from '@wgtechlabs/nuvex';
|
|
41
|
+
*
|
|
42
|
+
* const client = new NuvexClient({
|
|
43
|
+
* memory: { ttl: 3600000, maxSize: 10000 },
|
|
44
|
+
* redis: { url: 'redis://localhost:6379', ttl: 86400 },
|
|
45
|
+
* postgres: {
|
|
46
|
+
* host: 'localhost',
|
|
47
|
+
* database: 'myapp',
|
|
48
|
+
* user: 'user',
|
|
49
|
+
* password: 'pass'
|
|
50
|
+
* }
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* await client.connect();
|
|
54
|
+
*
|
|
55
|
+
* // Set data (automatically stored in all layers)
|
|
56
|
+
* await client.set('user:123', { name: 'John', email: 'john@example.com' });
|
|
57
|
+
*
|
|
58
|
+
* // Get data (automatically checks Memory → Redis → PostgreSQL)
|
|
59
|
+
* const user = await client.get('user:123');
|
|
60
|
+
* ```
|
|
61
|
+
* * ## Use Cases
|
|
62
|
+
*
|
|
63
|
+
* - **Session Management**: Store user sessions with automatic expiration
|
|
64
|
+
* - **API Caching**: Cache API responses with intelligent invalidation
|
|
65
|
+
* - **Configuration Storage**: Store application settings with fallback
|
|
66
|
+
* - **Real-time Data**: Handle high-frequency data with performance optimization
|
|
67
|
+
* - **Application State**: Store application state and user preferences
|
|
68
|
+
* - **Microservices**: Shared data layer across distributed services
|
|
69
|
+
*
|
|
70
|
+
* @author Waren Gonzaga, WG Technology Labs
|
|
71
|
+
* @since 2025
|
|
72
|
+
* @see {@link https://github.com/wgtechlabs/nuvex} GitHub Repository
|
|
73
|
+
* @see {@link https://wgtechlabs.com} WG Technology Labs
|
|
74
|
+
*
|
|
75
|
+
* @packageDocumentation
|
|
76
|
+
*/
|
|
77
|
+
export { StorageEngine } from './core/engine.js';
|
|
78
|
+
export { NuvexClient } from './core/client.js';
|
|
79
|
+
export * from './core/database.js';
|
|
80
|
+
export type * from './types/index.js';
|
|
81
|
+
export type * from './interfaces/index.js';
|
|
82
|
+
export { NuvexClient as Nuvex } from './core/client.js';
|
|
83
|
+
export { NuvexClient as Client } from './core/client.js';
|
|
84
|
+
export { StorageEngine as Engine } from './core/engine.js';
|
|
85
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,cAAc,oBAAoB,CAAC;AAGnC,mBAAmB,kBAAkB,CAAC;AACtC,mBAAmB,uBAAuB,CAAC;AAG3C,OAAO,EAAE,WAAW,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGxD,OAAO,EAAE,WAAW,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,aAAa,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
|