triva 0.0.2 → 0.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/LICENSE +21 -0
- package/README.md +416 -0
- package/index.d.ts +91 -0
- package/lib/cache.js +112 -0
- package/lib/cookie-parser.js +114 -0
- package/lib/db-adapters.js +580 -0
- package/lib/error-tracker.js +353 -0
- package/lib/index.js +655 -0
- package/lib/log.js +261 -0
- package/lib/middleware.js +237 -0
- package/lib/ua-parser.js +130 -0
- package/package.json +29 -8
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kris Powers
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img style="border-radius: 10px; width: 120px; height 120px;" src=".github/assets/triva-logo.png" >
|
|
5
|
+
</P>
|
|
6
|
+
|
|
7
|
+
<h1 align="center">Triva</h1>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
A Node.js HTTP Server Framework built for enterprises
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
Triva is an enterprise-grade Node.js HTTP framework with centralized configuration, database adapters, advanced middleware, and complete developer visibility.
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
> [!IMPORTANT]
|
|
20
|
+
> **v0.3.0 - Pre Release**
|
|
21
|
+
>
|
|
22
|
+
> This release is intended solely for the **continued development & testing of Triva & its capabilities.** Expect **rapid updates containing bug fixes, feature reworks, & framekwork optimization** going forward, until the official release of v1.0.0 and onward.
|
|
23
|
+
>
|
|
24
|
+
> During the **Pre-release** phase, a wide range of efforts to build a **user-friendly documentation interface** will also be in the works. Until the release of that interface, it's recommended that developers testing Triva refer to the docs found below.
|
|
25
|
+
>
|
|
26
|
+
>**If you're looking to contribute in any capacity, please feel free to submit a pull request or issue ticket for review.**
|
|
27
|
+
>
|
|
28
|
+
>
|
|
29
|
+
|
|
30
|
+
## ✨ Features
|
|
31
|
+
|
|
32
|
+
- 🎯 **Centralized Configuration** - Everything configured in `build()`
|
|
33
|
+
- 🗄️ **Multiple Databases** - Memory, MongoDB, Redis, PostgreSQL, MySQL
|
|
34
|
+
- 📦 **Auto-Detection** - Helpful errors if database packages aren't installed
|
|
35
|
+
- 🚀 **Zero Dependencies** (core) - Optional database drivers as needed
|
|
36
|
+
- 🛡️ **Advanced Throttling** - Sliding window, burst protection, auto-ban
|
|
37
|
+
- 📊 **Comprehensive Logging** - Request logs with cookies, UA data
|
|
38
|
+
- ⚡ **Built-in Caching** - Works with any supported database
|
|
39
|
+
- 🔍 **Error Tracking** - Automatic error capture with full context
|
|
40
|
+
- 🍪 **Cookie Parser** - Parse and set cookies easily
|
|
41
|
+
- 📥 **File Operations** - Download and send files
|
|
42
|
+
- 🌐 **JSONP Support** - Cross-domain API calls
|
|
43
|
+
- ⚙️ **Custom Middleware** - Full Express-style middleware support
|
|
44
|
+
|
|
45
|
+
## 📦 Installation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install triva
|
|
49
|
+
|
|
50
|
+
# Optional: Install database driver if needed
|
|
51
|
+
npm install mongodb # For MongoDB
|
|
52
|
+
npm install redis # For Redis
|
|
53
|
+
npm install pg # For PostgreSQL
|
|
54
|
+
npm install mysql2 # For MySQL
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 🚀 Quick Start
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
import { build, get, listen } from 'triva';
|
|
61
|
+
|
|
62
|
+
// All configuration in one place!
|
|
63
|
+
await build({
|
|
64
|
+
env: 'development',
|
|
65
|
+
|
|
66
|
+
cache: {
|
|
67
|
+
type: 'memory',
|
|
68
|
+
retention: 600000
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
throttle: {
|
|
72
|
+
limit: 100,
|
|
73
|
+
window_ms: 60000
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
get('/', (req, res) => {
|
|
78
|
+
res.json({ message: 'Hello World!' });
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
listen(3000);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## 🎯 Centralized Configuration
|
|
85
|
+
|
|
86
|
+
Everything is configured in `build()`:
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
await build({
|
|
90
|
+
env: 'development',
|
|
91
|
+
|
|
92
|
+
// Cache Configuration
|
|
93
|
+
cache: {
|
|
94
|
+
type: 'mongodb', // memory, mongodb, redis, postgresql, mysql
|
|
95
|
+
retention: 600000, // 10 minutes
|
|
96
|
+
limit: 10000,
|
|
97
|
+
|
|
98
|
+
database: {
|
|
99
|
+
uri: 'mongodb://localhost:27017',
|
|
100
|
+
database: 'triva',
|
|
101
|
+
collection: 'cache'
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
// Throttle Configuration
|
|
106
|
+
throttle: {
|
|
107
|
+
limit: 100,
|
|
108
|
+
window_ms: 60000,
|
|
109
|
+
burst_limit: 20,
|
|
110
|
+
burst_window_ms: 1000,
|
|
111
|
+
ban_threshold: 5,
|
|
112
|
+
ban_ms: 300000
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
// Log Retention
|
|
116
|
+
retention: {
|
|
117
|
+
enabled: true,
|
|
118
|
+
maxEntries: 10000
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
// Error Tracking
|
|
122
|
+
errorTracking: {
|
|
123
|
+
enabled: true,
|
|
124
|
+
maxEntries: 5000
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## 🗄️ Database Support
|
|
130
|
+
|
|
131
|
+
### Memory (Built-in)
|
|
132
|
+
```javascript
|
|
133
|
+
await build({
|
|
134
|
+
cache: { type: 'memory' }
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### MongoDB
|
|
139
|
+
```bash
|
|
140
|
+
npm install mongodb
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
await build({
|
|
145
|
+
cache: {
|
|
146
|
+
type: 'mongodb',
|
|
147
|
+
database: {
|
|
148
|
+
uri: 'mongodb://localhost:27017',
|
|
149
|
+
database: 'triva'
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Redis
|
|
156
|
+
```bash
|
|
157
|
+
npm install redis
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
await build({
|
|
162
|
+
cache: {
|
|
163
|
+
type: 'redis',
|
|
164
|
+
database: {
|
|
165
|
+
host: 'localhost',
|
|
166
|
+
port: 6379
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### PostgreSQL
|
|
173
|
+
```bash
|
|
174
|
+
npm install pg
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
```javascript
|
|
178
|
+
await build({
|
|
179
|
+
cache: {
|
|
180
|
+
type: 'postgresql',
|
|
181
|
+
database: {
|
|
182
|
+
host: 'localhost',
|
|
183
|
+
port: 5432,
|
|
184
|
+
database: 'triva',
|
|
185
|
+
user: 'postgres',
|
|
186
|
+
password: 'password'
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### MySQL
|
|
193
|
+
```bash
|
|
194
|
+
npm install mysql2
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
await build({
|
|
199
|
+
cache: {
|
|
200
|
+
type: 'mysql',
|
|
201
|
+
database: {
|
|
202
|
+
host: 'localhost',
|
|
203
|
+
port: 3306,
|
|
204
|
+
database: 'triva',
|
|
205
|
+
user: 'root',
|
|
206
|
+
password: 'password'
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**Helpful Errors:**
|
|
213
|
+
```
|
|
214
|
+
❌ MongoDB package not found.
|
|
215
|
+
|
|
216
|
+
Install it with: npm install mongodb
|
|
217
|
+
|
|
218
|
+
Then restart your server.
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## 📖 Core Features
|
|
222
|
+
|
|
223
|
+
### Routing
|
|
224
|
+
|
|
225
|
+
```javascript
|
|
226
|
+
import { get, post, put, delete as del } from 'triva';
|
|
227
|
+
|
|
228
|
+
get('/users', (req, res) => {
|
|
229
|
+
res.json({ users: [] });
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
get('/users/:id', (req, res) => {
|
|
233
|
+
const { id } = req.params;
|
|
234
|
+
res.json({ userId: id });
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
post('/users', async (req, res) => {
|
|
238
|
+
const data = await req.json();
|
|
239
|
+
res.json({ created: true });
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Cookies
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
import { use, cookieParser } from 'triva';
|
|
247
|
+
|
|
248
|
+
use(cookieParser());
|
|
249
|
+
|
|
250
|
+
get('/login', (req, res) => {
|
|
251
|
+
res.cookie('sessionId', 'abc123', {
|
|
252
|
+
httpOnly: true,
|
|
253
|
+
maxAge: 3600000
|
|
254
|
+
});
|
|
255
|
+
res.json({ success: true });
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
get('/profile', (req, res) => {
|
|
259
|
+
const sessionId = req.cookies.sessionId;
|
|
260
|
+
res.json({ sessionId });
|
|
261
|
+
});
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### File Operations
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
// Download file
|
|
268
|
+
get('/download', (req, res) => {
|
|
269
|
+
res.download('/path/to/file.pdf', 'report.pdf');
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// Send file
|
|
273
|
+
get('/view', (req, res) => {
|
|
274
|
+
res.sendFile('/path/to/document.pdf');
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### JSONP
|
|
279
|
+
|
|
280
|
+
```javascript
|
|
281
|
+
get('/api/data', (req, res) => {
|
|
282
|
+
res.jsonp({ users: ['Alice', 'Bob'] });
|
|
283
|
+
});
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Custom Middleware
|
|
287
|
+
|
|
288
|
+
```javascript
|
|
289
|
+
use((req, res, next) => {
|
|
290
|
+
console.log(`${req.method} ${req.url}`);
|
|
291
|
+
next();
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Logging
|
|
296
|
+
|
|
297
|
+
```javascript
|
|
298
|
+
import { log } from 'triva';
|
|
299
|
+
|
|
300
|
+
// Get logs
|
|
301
|
+
const logs = await log.get({ limit: 100 });
|
|
302
|
+
|
|
303
|
+
// Export logs
|
|
304
|
+
await log.export('all', 'my-logs.json');
|
|
305
|
+
|
|
306
|
+
// Get stats
|
|
307
|
+
const stats = await log.getStats();
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Error Tracking
|
|
311
|
+
|
|
312
|
+
```javascript
|
|
313
|
+
import { errorTracker } from 'triva';
|
|
314
|
+
|
|
315
|
+
// Get errors
|
|
316
|
+
const errors = await errorTracker.get({ severity: 'critical' });
|
|
317
|
+
|
|
318
|
+
// Get stats
|
|
319
|
+
const stats = await errorTracker.getStats();
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## 📊 Complete Example
|
|
323
|
+
|
|
324
|
+
```javascript
|
|
325
|
+
import {
|
|
326
|
+
build,
|
|
327
|
+
use,
|
|
328
|
+
get,
|
|
329
|
+
post,
|
|
330
|
+
listen,
|
|
331
|
+
cookieParser,
|
|
332
|
+
log
|
|
333
|
+
} from 'triva';
|
|
334
|
+
|
|
335
|
+
// Centralized configuration
|
|
336
|
+
await build({
|
|
337
|
+
env: 'production',
|
|
338
|
+
|
|
339
|
+
cache: {
|
|
340
|
+
type: 'redis',
|
|
341
|
+
database: {
|
|
342
|
+
host: process.env.REDIS_HOST,
|
|
343
|
+
port: 6379
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
throttle: {
|
|
348
|
+
limit: 100,
|
|
349
|
+
window_ms: 60000
|
|
350
|
+
},
|
|
351
|
+
|
|
352
|
+
retention: {
|
|
353
|
+
enabled: true,
|
|
354
|
+
maxEntries: 50000
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
// Middleware
|
|
359
|
+
use(cookieParser());
|
|
360
|
+
|
|
361
|
+
// Routes
|
|
362
|
+
get('/', (req, res) => {
|
|
363
|
+
res.json({ status: 'ok', cookies: req.cookies });
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
get('/api/users/:id', (req, res) => {
|
|
367
|
+
res.json({ userId: req.params.id });
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
post('/api/users', async (req, res) => {
|
|
371
|
+
const data = await req.json();
|
|
372
|
+
res.status(201).json({ created: true, data });
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
get('/download/report', (req, res) => {
|
|
376
|
+
res.download('./reports/annual-report.pdf');
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
get('/admin/logs/export', async (req, res) => {
|
|
380
|
+
const result = await log.export({ limit: 1000 });
|
|
381
|
+
res.json({ exported: result.count });
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
// Start server
|
|
385
|
+
listen(process.env.PORT || 3000, () => {
|
|
386
|
+
console.log('Server running');
|
|
387
|
+
});
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## 🔧 Response Methods
|
|
391
|
+
|
|
392
|
+
```javascript
|
|
393
|
+
res.json(data) // Send JSON
|
|
394
|
+
res.send(data) // Auto-detect (HTML/JSON/text)
|
|
395
|
+
res.html(html) // Send HTML
|
|
396
|
+
res.status(code) // Set status code
|
|
397
|
+
res.header(name, value) // Set header
|
|
398
|
+
res.redirect(url, code) // Redirect
|
|
399
|
+
res.jsonp(data) // Send JSONP
|
|
400
|
+
res.download(path, filename) // Download file
|
|
401
|
+
res.sendFile(path, options) // Send file
|
|
402
|
+
res.cookie(name, value, options) // Set cookie
|
|
403
|
+
res.clearCookie(name) // Clear cookie
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## ⚡ Performance
|
|
407
|
+
|
|
408
|
+
- **Memory**: Fastest (built-in)
|
|
409
|
+
- **Redis**: Fastest (external DB)
|
|
410
|
+
- **MongoDB**: Fast (document store)
|
|
411
|
+
- **PostgreSQL**: Fast (ACID compliance)
|
|
412
|
+
- **MySQL**: Fast (traditional)
|
|
413
|
+
|
|
414
|
+
## 📄 License
|
|
415
|
+
|
|
416
|
+
MIT
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Triva Type Definitions
|
|
2
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
|
|
4
|
+
export interface ServerOptions {
|
|
5
|
+
env?: 'development' | 'production';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface CookieOptions {
|
|
9
|
+
maxAge?: number;
|
|
10
|
+
expires?: Date | string;
|
|
11
|
+
httpOnly?: boolean;
|
|
12
|
+
secure?: boolean;
|
|
13
|
+
sameSite?: 'Strict' | 'Lax' | 'None' | boolean;
|
|
14
|
+
path?: string;
|
|
15
|
+
domain?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface SendFileOptions {
|
|
19
|
+
contentType?: string;
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ResponseHelpers extends ServerResponse {
|
|
24
|
+
status(code: number): this;
|
|
25
|
+
header(name: string, value: string): this;
|
|
26
|
+
json(data: any): this;
|
|
27
|
+
send(data: any): this;
|
|
28
|
+
html(html: string): this;
|
|
29
|
+
redirect(url: string, code?: number): this;
|
|
30
|
+
jsonp(data: any, callbackParam?: string): this;
|
|
31
|
+
download(filepath: string, filename?: string): this;
|
|
32
|
+
sendFile(filepath: string, options?: SendFileOptions): this;
|
|
33
|
+
cookie(name: string, value: string, options?: CookieOptions): this;
|
|
34
|
+
clearCookie(name: string, options?: CookieOptions): this;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface RequestContext {
|
|
38
|
+
req: IncomingMessage;
|
|
39
|
+
res: ResponseHelpers;
|
|
40
|
+
params: Record<string, string>;
|
|
41
|
+
query: Record<string, string | string[]>;
|
|
42
|
+
pathname: string;
|
|
43
|
+
cookies: Record<string, string>;
|
|
44
|
+
json(): Promise<any>;
|
|
45
|
+
text(): Promise<string>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type RouteHandler = (req: RequestContext, res: ResponseHelpers) => void | Promise<void>;
|
|
49
|
+
export type MiddlewareFunction = (req: IncomingMessage, res: ServerResponse, next: (err?: Error) => void) => void;
|
|
50
|
+
|
|
51
|
+
export function build(options?: ServerOptions): void;
|
|
52
|
+
export function middleware(options?: any): void;
|
|
53
|
+
export function use(middleware: MiddlewareFunction): void;
|
|
54
|
+
export function get(pattern: string, handler: RouteHandler): void;
|
|
55
|
+
export function post(pattern: string, handler: RouteHandler): void;
|
|
56
|
+
export function put(pattern: string, handler: RouteHandler): void;
|
|
57
|
+
export function patch(pattern: string, handler: RouteHandler): void;
|
|
58
|
+
export { del as delete };
|
|
59
|
+
export function del(pattern: string, handler: RouteHandler): void;
|
|
60
|
+
export function listen(port: number, callback?: () => void): any;
|
|
61
|
+
export function setErrorHandler(handler: (err: Error, req: IncomingMessage, res: ServerResponse) => void): void;
|
|
62
|
+
export function setNotFoundHandler(handler: (req: IncomingMessage, res: ServerResponse) => void): void;
|
|
63
|
+
|
|
64
|
+
export const log: {
|
|
65
|
+
get(filter?: any): Promise<any[]>;
|
|
66
|
+
getStats(): Promise<any>;
|
|
67
|
+
clear(): Promise<any>;
|
|
68
|
+
search(query: string): Promise<any[]>;
|
|
69
|
+
export(filter?: any, filename?: string): Promise<any>;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const cache: {
|
|
73
|
+
get(key: string): Promise<any>;
|
|
74
|
+
set(key: string, value: any, ttl?: number): Promise<boolean>;
|
|
75
|
+
delete(key: string): Promise<boolean>;
|
|
76
|
+
clear(): Promise<number>;
|
|
77
|
+
stats(): Promise<any>;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const errorTracker: {
|
|
81
|
+
configure(options: any): any;
|
|
82
|
+
capture(error: Error, context?: any): Promise<any>;
|
|
83
|
+
get(filter?: any): Promise<any[]>;
|
|
84
|
+
getById(id: string): Promise<any>;
|
|
85
|
+
resolve(id: string): Promise<any>;
|
|
86
|
+
getStats(): Promise<any>;
|
|
87
|
+
clear(): Promise<any>;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export function configCache(options: any): void;
|
|
91
|
+
export function cookieParser(secret?: string): MiddlewareFunction;
|
package/lib/cache.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Triva - Cache Manager with Database Adapters
|
|
3
|
+
* Copyright (c) 2026 Kris Powers
|
|
4
|
+
* License MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
import { createAdapter } from './db-adapters.js';
|
|
10
|
+
|
|
11
|
+
/* ---------------- Cache Manager ---------------- */
|
|
12
|
+
class CacheManager {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.adapter = null;
|
|
15
|
+
this.config = {
|
|
16
|
+
enabled: true,
|
|
17
|
+
type: 'memory',
|
|
18
|
+
retention: 10 * 60 * 1000, // 10 minutes default
|
|
19
|
+
limit: 100000
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async configure(options = {}) {
|
|
24
|
+
this.config = {
|
|
25
|
+
...this.config,
|
|
26
|
+
enabled: options.cache_data !== false,
|
|
27
|
+
type: options.cache_type || options.type || 'memory',
|
|
28
|
+
retention: options.cache_retention || options.retention || this.config.retention,
|
|
29
|
+
limit: options.cache_limit || options.limit || this.config.limit
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Create adapter
|
|
33
|
+
try {
|
|
34
|
+
const adapterConfig = options.database || options.db || {};
|
|
35
|
+
this.adapter = createAdapter(this.config.type, adapterConfig);
|
|
36
|
+
await this.adapter.connect();
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error('❌ Cache adapter error:', error.message);
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async get(key) {
|
|
46
|
+
if (!this.config.enabled || !this.adapter) return null;
|
|
47
|
+
return await this.adapter.get(key);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async set(key, value, ttl = null) {
|
|
51
|
+
if (!this.config.enabled || !this.adapter) return false;
|
|
52
|
+
const actualTtl = ttl !== null ? ttl : this.config.retention;
|
|
53
|
+
return await this.adapter.set(key, value, actualTtl);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async delete(key) {
|
|
57
|
+
if (!this.adapter) return false;
|
|
58
|
+
return await this.adapter.delete(key);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async has(key) {
|
|
62
|
+
if (!this.adapter) return false;
|
|
63
|
+
return await this.adapter.has(key);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async clear() {
|
|
67
|
+
if (!this.adapter) return 0;
|
|
68
|
+
return await this.adapter.clear();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async keys(pattern = null) {
|
|
72
|
+
if (!this.adapter) return [];
|
|
73
|
+
return await this.adapter.keys(pattern);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async size() {
|
|
77
|
+
if (!this.adapter) return 0;
|
|
78
|
+
const allKeys = await this.adapter.keys();
|
|
79
|
+
return allKeys.length;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async stats() {
|
|
83
|
+
const size = await this.size();
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
size,
|
|
87
|
+
maxSize: this.config.limit,
|
|
88
|
+
active: size,
|
|
89
|
+
config: {
|
|
90
|
+
enabled: this.config.enabled,
|
|
91
|
+
type: this.config.type,
|
|
92
|
+
retention: this.config.retention,
|
|
93
|
+
limit: this.config.limit
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
shutdown() {
|
|
99
|
+
if (this.adapter) {
|
|
100
|
+
this.adapter.disconnect();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* ---------------- Export Singleton ---------------- */
|
|
106
|
+
const cache = new CacheManager();
|
|
107
|
+
|
|
108
|
+
function configCache(options) {
|
|
109
|
+
return cache.configure(options);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { cache, configCache, CacheManager };
|