triva 0.0.2 → 0.3.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.
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 };