@pixagram/lacerta-db 0.3.0 → 0.5.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/readme.md CHANGED
@@ -1,207 +1,1245 @@
1
- LacertaDB (@pixagram/lacerta-db)
2
- LacertaDB is a Javascript IndexedDB Database for Web Browsers. Simple, Fast, Secure.
1
+ # LacertaDB
2
+ ![](https://github.com/pixagram-blockchain/LacertaDB/blob/main/logo.webp?raw=true)
3
+
4
+ > 🦎 **LacertaDB v4.0.3** - A powerful, feature-rich browser-based document database with encryption, compression, and advanced querying capabilities.
5
+
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![Version](https://img.shields.io/badge/version-4.0.3-blue.svg)]()
8
+ [![Browser Compatible](https://img.shields.io/badge/browser-compatible-green.svg)]()
9
+
10
+ ## 📚 Table of Contents
11
+
12
+ - [✨ Features](#-features)
13
+ - [🚀 Quick Start](#-quick-start)
14
+ - [📦 Installation](#-installation)
15
+ - [🎯 Basic Usage](#-basic-usage)
16
+ - [🔧 Core Concepts](#-core-concepts)
17
+ - [Database](#database)
18
+ - [Collections](#collections)
19
+ - [Documents](#documents)
20
+ - [🔍 Querying](#-querying)
21
+ - [Basic Queries](#basic-queries)
22
+ - [Advanced Queries](#advanced-queries)
23
+ - [Aggregation Pipeline](#aggregation-pipeline)
24
+ - [🔐 Security Features](#-security-features)
25
+ - [Encryption](#encryption)
26
+ - [Password Protection](#password-protection)
27
+ - [📎 Attachments](#-attachments)
28
+ - [⚡ Performance](#-performance)
29
+ - [Compression](#compression)
30
+ - [Performance Monitoring](#performance-monitoring)
31
+ - [Query Caching](#query-caching)
32
+ - [🔄 Data Migration](#-data-migration)
33
+ - [💾 Backup & Restore](#-backup--restore)
34
+ - [🛠️ Advanced Features](#️-advanced-features)
35
+ - [Batch Operations](#batch-operations)
36
+ - [Event System](#event-system)
37
+ - [Quick Store](#quick-store)
38
+ - [📊 Storage Management](#-storage-management)
39
+ - [🎨 API Reference](#-api-reference)
40
+ - [💡 Examples](#-examples)
41
+ - [🐛 Error Handling](#-error-handling)
42
+ - [📝 Best Practices](#-best-practices)
43
+ - [🤝 Contributing](#-contributing)
44
+
45
+ ## ✨ Features
46
+
47
+ 🎯 **Core Features**
48
+ - 📁 **Document-based storage** using IndexedDB
49
+ - 🔍 **MongoDB-like query syntax** for familiar operations
50
+ - 🔐 **AES-256-GCM encryption** with PBKDF2 key derivation
51
+ - 🗜️ **Built-in compression** using CompressionStream API
52
+ - 📎 **File attachments** via Origin Private File System (OPFS)
53
+ - ⚡ **High performance** with async operations and caching
54
+
55
+ 🚀 **Advanced Capabilities**
56
+ - 📊 **Aggregation pipeline** for complex data processing
57
+ - 🔄 **Schema migration system** for version management
58
+ - 📈 **Performance monitoring** with real-time metrics
59
+ - 🎭 **Event-driven architecture** with hooks
60
+ - 💾 **Import/Export functionality** with encryption support
61
+ - 🔧 **Batch operations** for efficient bulk processing
62
+
63
+ ## 🚀 Quick Start
64
+
65
+ ```javascript
66
+ import { LacertaDB } from './lacertadb.js';
67
+
68
+ // Initialize LacertaDB
69
+ const lacerta = new LacertaDB();
70
+
71
+ // Get or create a database
72
+ const db = await lacerta.getDatabase('myApp');
73
+
74
+ // Create a collection
75
+ const users = await db.createCollection('users');
76
+
77
+ // Add a document
78
+ const userId = await users.add({
79
+ name: 'Alice Johnson',
80
+ email: 'alice@example.com',
81
+ age: 28,
82
+ tags: ['developer', 'javascript']
83
+ });
84
+
85
+ // Query documents
86
+ const results = await users.query({
87
+ age: { $gte: 25 },
88
+ tags: { $in: ['developer'] }
89
+ });
90
+
91
+ console.log('Found users:', results);
92
+ ```
93
+
94
+ ## 📦 Installation
95
+
96
+ ### NPM/Yarn Installation
97
+
98
+ ```bash
99
+ npm install @pixagram/lacertadb
100
+ # or
101
+ yarn add @pixagram/lacertadb
102
+ ```
103
+
104
+ ### Browser Module
105
+
106
+ ```html
107
+ <script type="module">
108
+ import { LacertaDB } from './lacertadb.js';
109
+ const lacerta = new LacertaDB();
110
+ </script>
111
+ ```
112
+
113
+ ### Dependencies
114
+
115
+ LacertaDB requires:
116
+ - `@pixagram/turboserial` - High-performance serialization
117
+ - `@pixagram/turbobase64` - Optimized Base64 encoding
118
+
119
+ ## 🎯 Basic Usage
120
+
121
+ ### Creating a Database and Collection
122
+
123
+ ```javascript
124
+ const lacerta = new LacertaDB();
125
+
126
+ // Create or get a database
127
+ const db = await lacerta.getDatabase('myDatabase');
128
+
129
+ // Create a collection with options
130
+ const products = await db.createCollection('products', {
131
+ compressed: true, // Enable compression by default
132
+ encrypted: false // Encryption disabled by default
133
+ });
134
+ ```
135
+
136
+ ### Adding Documents
137
+
138
+ ```javascript
139
+ // Simple document
140
+ await products.add({
141
+ name: 'Laptop',
142
+ price: 999.99,
143
+ inStock: true
144
+ });
145
+
146
+ // Document with options
147
+ await products.add(
148
+ {
149
+ name: 'Secure Document',
150
+ data: 'sensitive information'
151
+ },
152
+ {
153
+ id: 'custom-id-123', // Custom ID
154
+ encrypted: true, // Encrypt this document
155
+ password: 'secretPassword', // Encryption password
156
+ compressed: true, // Compress the document
157
+ permanent: true // Mark as permanent (won't be auto-deleted)
158
+ }
159
+ );
160
+ ```
3
161
 
4
- LacertaDB offers a powerful, modern, and feature-rich interface for working with IndexedDB in the browser. It's designed as a document-oriented database, providing a developer-friendly API similar to MongoDB. It prioritizes security, performance, and advanced data handling capabilities right out of the box.
162
+ ### Retrieving Documents
5
163
 
6
- ✨ Key Features
7
- Simple API: An intuitive and modern API that makes database operations straightforward.
164
+ ```javascript
165
+ // Get by ID
166
+ const product = await products.get('custom-id-123', {
167
+ password: 'secretPassword' // Required for encrypted documents
168
+ });
169
+
170
+ // Get all documents
171
+ const allProducts = await products.getAll();
8
172
 
9
- Strong Encryption: Built-in AES-GCM encryption to secure sensitive documents with a password.
173
+ // Get with attachments
174
+ const withFiles = await products.get('doc-id', {
175
+ includeAttachments: true
176
+ });
177
+ ```
10
178
 
11
- Efficient Compression: Automatic data compression using the Compression Streams API to save storage space.
179
+ ## 🔧 Core Concepts
12
180
 
13
- OPFS Attachments: Store large files like images or videos efficiently using the Origin Private File System (OPFS), linking them directly to your documents.
181
+ ### Database
14
182
 
15
- Advanced Queries: A powerful MongoDB-like query engine with support for complex operators ($gt, $in, $regex, etc.) and logical combinations ($and, $or).
183
+ The database is the top-level container for your collections.
16
184
 
17
- Aggregation Pipeline: Perform complex data analysis and transformations directly in the database with a multi-stage aggregation pipeline ($match, $group, $sort, etc.).
185
+ ```javascript
186
+ // Get existing or create new database
187
+ const db = await lacerta.getDatabase('appDB');
18
188
 
19
- High-Performance Serialization: Uses turboserial and turbobase64 instead of JSON for faster serialization and deserialization of data.
189
+ // List all collections
190
+ const collections = db.listCollections();
20
191
 
21
- Automatic Cleanup: Set storage limits and let the database automatically manage space by removing the oldest, non-permanent documents.
192
+ // Get database statistics
193
+ const stats = db.getStats();
194
+ console.log(`Total size: ${stats.totalSizeKB} KB`);
195
+ console.log(`Total documents: ${stats.totalDocuments}`);
22
196
 
23
- Full-Featured: Includes batch operations, query caching, metadata management, and a migration system to handle schema changes over time.
197
+ // Configure database settings
198
+ db.updateSettings({
199
+ sizeLimitKB: 50000, // 50MB limit
200
+ bufferLimitKB: 40000, // Start cleanup at 40MB
201
+ freeSpaceEvery: 60000 // Run cleanup every minute
202
+ });
203
+ ```
24
204
 
25
- 🚀 Installation
26
- Install the package using your favorite package manager.
205
+ ### Collections
27
206
 
28
- npm install @pixagram/lacerta-db
207
+ Collections are containers for documents of similar type.
29
208
 
30
- ⚡ Quick Start
31
- Here's how to get up and running with LacertaDB in just a few lines of code.
209
+ ```javascript
210
+ // Create collection
211
+ const posts = await db.createCollection('posts');
32
212
 
33
- // Import the default instance
34
- import LacertaDB from '@pixagram/lacerta-db';
213
+ // Get existing collection
214
+ const existingPosts = await db.getCollection('posts');
35
215
 
36
- async function main() {
37
- try {
38
- // 1. Get a database instance
39
- const db = await LacertaDB.getDatabase('my-app-db');
216
+ // Collection operations
217
+ await posts.clear(); // Remove all documents
218
+ await db.dropCollection('posts'); // Delete collection entirely
40
219
 
41
- // 2. Get or create a collection
42
- // Collections are created automatically on first access
43
- const users = await db.getCollection('users');
220
+ // Collection events
221
+ posts.on('afterAdd', (doc) => {
222
+ console.log('Document added:', doc._id);
223
+ });
224
+ ```
225
+
226
+ ### Documents
227
+
228
+ Documents are JavaScript objects with automatic metadata.
229
+
230
+ ```javascript
231
+ // Document structure
232
+ const doc = {
233
+ // User data
234
+ title: 'My Post',
235
+ content: 'Lorem ipsum...',
236
+
237
+ // Automatic metadata (added by LacertaDB)
238
+ _id: 'doc_1234567890_abc', // Auto-generated unique ID
239
+ _created: 1704067200000, // Creation timestamp
240
+ _modified: 1704067200000, // Last modification timestamp
241
+ _permanent: false, // Deletion protection flag
242
+ };
243
+ ```
44
244
 
45
- // 3. Add a new document
46
- const newUserId = await users.add({
47
- name: 'Alex',
48
- level: 10,
49
- joined: new Date()
50
- });
51
- console.log(`User created with ID: ${newUserId}`);
245
+ ## 🔍 Querying
52
246
 
53
- // 4. Get a document by its ID
54
- const user = await users.get(newUserId);
55
- console.log('Retrieved user:', user);
247
+ ### Basic Queries
56
248
 
57
- // 5. Query for documents
58
- const highLevelUsers = await users.query({ level: { '$gt': 5 } });
59
- console.log('High-level users:', highLevelUsers);
249
+ ```javascript
250
+ // Find all documents matching criteria
251
+ const results = await users.query({
252
+ age: 30, // Exact match
253
+ 'address.city': 'New York' // Nested field
254
+ });
60
255
 
61
- } catch (error) {
62
- console.error('Database operation failed:', error);
256
+ // With options
257
+ const paginatedResults = await users.query(
258
+ { status: 'active' },
259
+ {
260
+ sort: { createdAt: -1 }, // Sort descending
261
+ skip: 10, // Skip first 10
262
+ limit: 20, // Limit to 20 results
263
+ projection: { // Select fields
264
+ name: 1,
265
+ email: 1,
266
+ _id: 0
267
+ }
63
268
  }
64
- }
269
+ );
270
+ ```
65
271
 
66
- main();
272
+ ### Advanced Queries
67
273
 
68
- 📖 API Reference
69
- Database
70
- The Database object is your main entry point for managing collections.
274
+ LacertaDB supports MongoDB-style query operators:
71
275
 
72
- getDatabase(name)
73
- Retrieves a database instance. If it doesn't exist, it's created.
276
+ #### Comparison Operators
74
277
 
75
- const db = await LacertaDB.getDatabase('my-app-db');
278
+ ```javascript
279
+ // $eq, $ne, $gt, $gte, $lt, $lte
280
+ await products.query({
281
+ price: { $gte: 100, $lte: 500 }
282
+ });
76
283
 
77
- getCollection(name)
78
- Retrieves a collection from the database. If it doesn't exist, it's created.
284
+ // $in, $nin
285
+ await users.query({
286
+ role: { $in: ['admin', 'moderator'] }
287
+ });
288
+ ```
79
289
 
80
- const usersCollection = await db.getCollection('users');
290
+ #### Logical Operators
81
291
 
82
- dropCollection(name)
83
- Deletes a collection and all of its documents and attachments.
292
+ ```javascript
293
+ // $and
294
+ await products.query({
295
+ $and: [
296
+ { price: { $lt: 1000 } },
297
+ { category: 'electronics' }
298
+ ]
299
+ });
84
300
 
85
- await db.dropCollection('users');
301
+ // $or
302
+ await users.query({
303
+ $or: [
304
+ { age: { $gte: 65 } },
305
+ { status: 'premium' }
306
+ ]
307
+ });
86
308
 
87
- Collection
88
- The Collection object provides methods to interact with documents.
309
+ // $not
310
+ await products.query({
311
+ discontinued: { $not: { $eq: true } }
312
+ });
313
+ ```
89
314
 
90
- add(data, [options])
91
- Adds a new document to the collection.
315
+ #### Array Operators
92
316
 
93
- data (Object): The document data.
317
+ ```javascript
318
+ // $all - Array contains all values
319
+ await posts.query({
320
+ tags: { $all: ['javascript', 'database'] }
321
+ });
94
322
 
95
- options (Object, optional):
323
+ // $elemMatch - Element matching
324
+ await orders.query({
325
+ items: {
326
+ $elemMatch: {
327
+ product: 'laptop',
328
+ quantity: { $gte: 2 }
329
+ }
330
+ }
331
+ });
96
332
 
97
- encrypted (boolean): Set to true to encrypt the document.
333
+ // $size - Array length
334
+ await users.query({
335
+ hobbies: { $size: 3 }
336
+ });
337
+ ```
98
338
 
99
- password (string): Required if encrypted is true.
339
+ #### Text Search
100
340
 
101
- permanent (boolean): If true, the document won't be deleted by the auto-cleanup process.
341
+ ```javascript
342
+ // $regex - Regular expression
343
+ await users.query({
344
+ email: { $regex: '@company\\.com$' }
345
+ });
102
346
 
103
- attachments (Array): An array of file attachments.
347
+ // $text - Case-insensitive text search
348
+ await posts.query({
349
+ content: { $text: 'javascript' }
350
+ });
351
+ ```
352
+
353
+ ### Aggregation Pipeline
354
+
355
+ Powerful data processing with aggregation stages:
356
+
357
+ ```javascript
358
+ // Sales analysis pipeline
359
+ const salesReport = await orders.aggregate([
360
+ // Stage 1: Filter orders
361
+ { $match: { status: 'completed' } },
362
+
363
+ // Stage 2: Group by customer
364
+ {
365
+ $group: {
366
+ _id: '$customerId',
367
+ totalSpent: { $sum: '$amount' },
368
+ orderCount: { $count: {} },
369
+ avgOrderValue: { $avg: '$amount' }
370
+ }
371
+ },
372
+
373
+ // Stage 3: Sort by total spent
374
+ { $sort: { totalSpent: -1 } },
375
+
376
+ // Stage 4: Limit to top 10
377
+ { $limit: 10 },
378
+
379
+ // Stage 5: Project final shape
380
+ {
381
+ $project: {
382
+ customer: '$_id',
383
+ metrics: {
384
+ total: '$totalSpent',
385
+ orders: '$orderCount',
386
+ average: '$avgOrderValue'
387
+ }
388
+ }
389
+ }
390
+ ]);
391
+ ```
392
+
393
+ #### Lookup (Join) Operations
394
+
395
+ ```javascript
396
+ // Join with another collection
397
+ const ordersWithProducts = await orders.aggregate([
398
+ {
399
+ $lookup: {
400
+ from: 'products', // Foreign collection
401
+ localField: 'productId', // Field in orders
402
+ foreignField: '_id', // Field in products
403
+ as: 'productDetails' // Output array field
404
+ }
405
+ }
406
+ ]);
407
+ ```
408
+
409
+ ## 🔐 Security Features
410
+
411
+ ### Encryption
412
+
413
+ Documents can be individually encrypted with AES-256-GCM:
414
+
415
+ ```javascript
416
+ // Add encrypted document
417
+ await users.add(
418
+ {
419
+ ssn: '123-45-6789',
420
+ bankAccount: 'SECRET123',
421
+ salary: 75000
422
+ },
423
+ {
424
+ encrypted: true,
425
+ password: 'strong-password-here',
426
+ permanent: true // Protect from auto-deletion
427
+ }
428
+ );
104
429
 
105
- const userId = await users.add({ name: 'Zoe' }, { permanent: true });
430
+ // Retrieve encrypted document
431
+ const userData = await users.get('user-id', {
432
+ password: 'strong-password-here' // Required for decryption
433
+ });
106
434
 
107
- get(id, [options])
108
- Retrieves a single document by its _id.
435
+ // Update encrypted document
436
+ await users.update('user-id',
437
+ { salary: 80000 },
438
+ {
439
+ encrypted: true,
440
+ password: 'strong-password-here'
441
+ }
442
+ );
443
+ ```
109
444
 
110
- id (string): The document ID.
445
+ ### Password Protection
111
446
 
112
- options (Object, optional):
447
+ Secure your exports and backups:
113
448
 
114
- password (string): Required to decrypt an encrypted document.
449
+ ```javascript
450
+ // Export with encryption
451
+ const encryptedExport = await db.export('encrypted', 'export-password');
115
452
 
116
- includeAttachments (boolean): If true, retrieves file data from OPFS.
453
+ // Import encrypted data
454
+ await db.import(encryptedExport, 'encrypted', 'export-password');
117
455
 
118
- const user = await users.get(userId);
456
+ // Create encrypted backup
457
+ const backup = await lacerta.createBackup('backup-password');
119
458
 
120
- query(filter, [options])
121
- Finds documents matching the filter object.
459
+ // Restore from encrypted backup
460
+ await lacerta.restoreBackup(backup, 'backup-password');
461
+ ```
122
462
 
123
- filter (Object): A MongoDB-style query object.
463
+ ## 📎 Attachments
124
464
 
125
- options (Object, optional):
465
+ Store files using the Origin Private File System:
126
466
 
127
- sort (Object): Sort order (e.g., { level: -1 }).
467
+ ```javascript
468
+ // Prepare files
469
+ const file1 = new File(['content'], 'document.pdf', { type: 'application/pdf' });
470
+ const file2 = new Blob(['image data'], { type: 'image/png' });
128
471
 
129
- limit (number): Max number of documents to return.
472
+ // Add document with attachments
473
+ const docId = await documents.add(
474
+ { title: 'Report with Files' },
475
+ {
476
+ attachments: [
477
+ file1,
478
+ file2,
479
+ {
480
+ name: 'custom.txt',
481
+ type: 'text/plain',
482
+ data: new TextEncoder().encode('Custom file content')
483
+ }
484
+ ]
485
+ }
486
+ );
130
487
 
131
- skip (number): Number of documents to skip.
488
+ // Retrieve with attachments
489
+ const docWithFiles = await documents.get(docId, {
490
+ includeAttachments: true
491
+ });
132
492
 
133
- const results = await users.query({ name: 'Alex' });
493
+ // Access attachments
494
+ docWithFiles._attachments.forEach(attachment => {
495
+ console.log(`File: ${attachment.name} (${attachment.size} bytes)`);
496
+ // attachment.data is Uint8Array
497
+ });
498
+ ```
134
499
 
135
- update(id, updates)
136
- Updates the data of a specific document.
500
+ ## ⚡ Performance
137
501
 
138
- await users.update(userId, { level: 11 });
502
+ ### Compression
139
503
 
140
- delete(id)
141
- Removes a document from the collection.
504
+ Reduce storage size with automatic compression:
142
505
 
143
- await users.delete(userId);
506
+ ```javascript
507
+ // Enable compression for all documents in collection
508
+ const compressedColl = await db.createCollection('largeDocs', {
509
+ compressed: true
510
+ });
144
511
 
145
- aggregate(pipeline)
146
- Processes documents through an aggregation pipeline.
512
+ // Per-document compression
513
+ await collection.add(largeData, {
514
+ compressed: true // Uses DeflateStream compression
515
+ });
516
+ ```
147
517
 
148
- const results = await users.aggregate([
149
- { '$match': { level: { '$gt': 5 } } },
150
- { '$group': { _id: null, averageLevel: { '$avg': '$level' } } }
151
- ]);
518
+ ### Performance Monitoring
519
+
520
+ Track database performance metrics:
521
+
522
+ ```javascript
523
+ // Start monitoring
524
+ lacerta.performanceMonitor.startMonitoring();
525
+
526
+ // Perform operations...
527
+
528
+ // Get performance stats
529
+ const stats = lacerta.performanceMonitor.getStats();
530
+ console.log(`Operations/sec: ${stats.opsPerSec}`);
531
+ console.log(`Avg latency: ${stats.avgLatency}ms`);
532
+ console.log(`Cache hit rate: ${stats.cacheHitRate}%`);
533
+ console.log(`Memory usage: ${stats.memoryUsageMB}MB`);
534
+
535
+ // Get optimization tips
536
+ const tips = lacerta.performanceMonitor.getOptimizationTips();
537
+ tips.forEach(tip => console.log(`💡 ${tip}`));
538
+
539
+ // Stop monitoring
540
+ lacerta.performanceMonitor.stopMonitoring();
541
+ ```
542
+
543
+ ### Query Caching
544
+
545
+ Queries are automatically cached for 60 seconds:
152
546
 
153
- 🛠️ Advanced Usage
154
- Encryption 🔒
155
- To store sensitive data, simply set the encrypted flag and provide a password. LacertaDB handles the rest.
547
+ ```javascript
548
+ // First query - hits database
549
+ const results1 = await users.query({ status: 'active' });
156
550
 
157
- const secretData = { account: '123-456', secret: 'my-secret-key' };
551
+ // Second identical query - served from cache
552
+ const results2 = await users.query({ status: 'active' });
158
553
 
159
- const docId = await db.collection('secrets').add(secretData, {
160
- encrypted: true,
161
- password: 'a-very-strong-password'
554
+ // Clear cache manually if needed
555
+ users.clearCache();
556
+ ```
557
+
558
+ ## 🔄 Data Migration
559
+
560
+ Version your schema changes:
561
+
562
+ ```javascript
563
+ const migrationManager = new MigrationManager(db);
564
+
565
+ // Define migrations
566
+ migrationManager.addMigration({
567
+ version: '2.0.0',
568
+ name: 'Add user roles',
569
+ up: async (doc) => {
570
+ if (doc.type === 'user' && !doc.role) {
571
+ return { ...doc, role: 'standard' };
572
+ }
573
+ return doc;
574
+ },
575
+ down: async (doc) => {
576
+ if (doc.type === 'user') {
577
+ const { role, ...rest } = doc;
578
+ return rest;
579
+ }
580
+ return doc;
581
+ }
582
+ });
583
+
584
+ // Run migrations
585
+ await migrationManager.runMigrations('2.0.0');
586
+
587
+ // Rollback if needed
588
+ await migrationManager.rollback('1.0.0');
589
+ ```
590
+
591
+ ## 💾 Backup & Restore
592
+
593
+ ### Database Export/Import
594
+
595
+ ```javascript
596
+ // Export single database
597
+ const exportData = await db.export('json');
598
+ // Save exportData to file or send to server
599
+
600
+ // Import data
601
+ const importResult = await db.import(exportData, 'json');
602
+ console.log(`Imported ${importResult.documents} documents`);
603
+
604
+ // Export with encryption
605
+ const secureExport = await db.export('encrypted', 'password123');
606
+ ```
607
+
608
+ ### Full System Backup
609
+
610
+ ```javascript
611
+ // Backup all databases
612
+ const systemBackup = await lacerta.createBackup();
613
+ // Optional: encrypt the backup
614
+ const encryptedBackup = await lacerta.createBackup('backup-password');
615
+
616
+ // Restore from backup
617
+ const restoreResult = await lacerta.restoreBackup(systemBackup);
618
+ console.log(`Restored: ${restoreResult.databases} databases`);
619
+ console.log(`Total documents: ${restoreResult.documents}`);
620
+ ```
621
+
622
+ ## 🛠️ Advanced Features
623
+
624
+ ### Batch Operations
625
+
626
+ Efficient bulk operations with transaction support:
627
+
628
+ ```javascript
629
+ // Batch insert
630
+ const documents = [
631
+ { name: 'Doc 1', value: 100 },
632
+ { name: 'Doc 2', value: 200 },
633
+ { name: 'Doc 3', value: 300 }
634
+ ];
635
+
636
+ const results = await collection.batchAdd(documents, {
637
+ compressed: true,
638
+ encrypted: false
162
639
  });
163
640
 
164
- // You MUST provide the same password to retrieve it
165
- const retrieved = await db.collection('secrets').get(docId, {
166
- password: 'a-very-strong-password'
641
+ // Check results
642
+ results.forEach(result => {
643
+ if (result.success) {
644
+ console.log(`✅ Added: ${result.id}`);
645
+ } else {
646
+ console.log(`❌ Failed: ${result.error}`);
647
+ }
167
648
  });
168
649
 
169
- File Attachments 📎
170
- You can attach files (like File objects or Uint8Array data) to a document. They are stored efficiently in the browser's Origin Private File System.
650
+ // Batch update
651
+ const updates = [
652
+ { id: 'doc1', data: { status: 'active' } },
653
+ { id: 'doc2', data: { status: 'inactive' } }
654
+ ];
655
+ await collection.batchUpdate(updates);
171
656
 
172
- // Create a sample file
173
- const fileContent = new TextEncoder().encode('This is the content of my file.');
174
- const attachment = {
175
- name: 'readme.txt',
176
- type: 'text/plain',
177
- data: fileContent
657
+ // Batch delete
658
+ const idsToDelete = ['doc3', 'doc4', 'doc5'];
659
+ await collection.batchDelete(idsToDelete);
660
+ ```
661
+
662
+ ### Event System
663
+
664
+ React to database operations:
665
+
666
+ ```javascript
667
+ // Collection-level events
668
+ collection.on('beforeAdd', async (data) => {
669
+ console.log('Validating document...');
670
+ // Perform validation
671
+ });
672
+
673
+ collection.on('afterAdd', async (doc) => {
674
+ console.log(`Document ${doc._id} added`);
675
+ // Send notification, update cache, etc.
676
+ });
677
+
678
+ collection.on('beforeUpdate', async ({ docId, updates }) => {
679
+ console.log(`Updating ${docId}`);
680
+ });
681
+
682
+ collection.on('afterDelete', async (docId) => {
683
+ console.log(`Document ${docId} deleted`);
684
+ // Cleanup related data
685
+ });
686
+
687
+ // Remove event listener
688
+ const handler = (doc) => console.log(doc);
689
+ collection.on('afterAdd', handler);
690
+ collection.off('afterAdd', handler);
691
+ ```
692
+
693
+ ### Quick Store
694
+
695
+ Fast localStorage-based storage for small data:
696
+
697
+ ```javascript
698
+ // Access QuickStore
699
+ const quickStore = db.quickStore;
700
+
701
+ // Store data
702
+ quickStore.add('user-prefs', {
703
+ theme: 'dark',
704
+ language: 'en',
705
+ notifications: true
706
+ });
707
+
708
+ // Retrieve data
709
+ const prefs = quickStore.get('user-prefs');
710
+
711
+ // Update
712
+ quickStore.update('user-prefs', { theme: 'light' });
713
+
714
+ // Get all stored items
715
+ const allItems = quickStore.getAll();
716
+
717
+ // Clear QuickStore
718
+ quickStore.clear();
719
+ ```
720
+
721
+ ## 📊 Storage Management
722
+
723
+ ### Size Limits and Auto-Cleanup
724
+
725
+ ```javascript
726
+ // Configure storage limits
727
+ db.updateSettings({
728
+ sizeLimitKB: 100000, // 100MB total limit
729
+ bufferLimitKB: 80000, // Start cleanup at 80MB
730
+ freeSpaceEvery: 30000 // Check every 30 seconds
731
+ });
732
+
733
+ // Manual cleanup
734
+ await collection.freeSpace();
735
+
736
+ // Mark documents as permanent
737
+ await collection.add(importantData, {
738
+ permanent: true // Won't be deleted during cleanup
739
+ });
740
+
741
+ // Check collection size
742
+ const stats = collection.metadata;
743
+ console.log(`Collection size: ${stats.sizeKB} KB`);
744
+ console.log(`Document count: ${stats.length}`);
745
+ ```
746
+
747
+ ### Storage Information
748
+
749
+ ```javascript
750
+ // Database statistics
751
+ const dbStats = db.getStats();
752
+ console.log(dbStats);
753
+ /* Output:
754
+ {
755
+ name: 'myDatabase',
756
+ totalSizeKB: 2457.3,
757
+ totalDocuments: 1250,
758
+ collections: [
759
+ {
760
+ name: 'users',
761
+ sizeKB: 1024.5,
762
+ documents: 500,
763
+ createdAt: '2024-01-01T00:00:00.000Z',
764
+ modifiedAt: '2024-01-15T10:30:00.000Z'
765
+ }
766
+ ]
767
+ }
768
+ */
769
+
770
+ // List all databases
771
+ const allDatabases = lacerta.listDatabases();
772
+ console.log('Available databases:', allDatabases);
773
+ ```
774
+
775
+ ## 🎨 API Reference
776
+
777
+ ### LacertaDB Class
778
+
779
+ | Method | Description | Returns |
780
+ |--------|-------------|---------|
781
+ | `getDatabase(name)` | Get or create a database | `Promise<Database>` |
782
+ | `dropDatabase(name)` | Delete a database | `Promise<void>` |
783
+ | `listDatabases()` | List all database names | `Array<string>` |
784
+ | `createBackup(password?)` | Create full system backup | `Promise<string>` |
785
+ | `restoreBackup(data, password?)` | Restore from backup | `Promise<Object>` |
786
+
787
+ ### Database Class
788
+
789
+ | Method | Description | Returns |
790
+ |--------|-------------|---------|
791
+ | `createCollection(name, options?)` | Create new collection | `Promise<Collection>` |
792
+ | `getCollection(name)` | Get existing collection | `Promise<Collection>` |
793
+ | `dropCollection(name)` | Delete collection | `Promise<void>` |
794
+ | `listCollections()` | Get collection names | `Array<string>` |
795
+ | `getStats()` | Get database statistics | `Object` |
796
+ | `updateSettings(settings)` | Update configuration | `void` |
797
+ | `export(format, password?)` | Export database | `Promise<string>` |
798
+ | `import(data, format, password?)` | Import data | `Promise<Object>` |
799
+ | `clearAll()` | Delete all collections | `Promise<void>` |
800
+
801
+ ### Collection Class
802
+
803
+ | Method | Description | Returns |
804
+ |--------|-------------|---------|
805
+ | `add(data, options?)` | Add document | `Promise<string>` |
806
+ | `get(id, options?)` | Get document by ID | `Promise<Object>` |
807
+ | `getAll(options?)` | Get all documents | `Promise<Array>` |
808
+ | `update(id, updates, options?)` | Update document | `Promise<string>` |
809
+ | `delete(id)` | Delete document | `Promise<void>` |
810
+ | `query(filter, options?)` | Query documents | `Promise<Array>` |
811
+ | `aggregate(pipeline)` | Run aggregation | `Promise<Array>` |
812
+ | `batchAdd(documents, options?)` | Add multiple documents | `Promise<Array>` |
813
+ | `batchUpdate(updates, options?)` | Update multiple documents | `Promise<Array>` |
814
+ | `batchDelete(ids)` | Delete multiple documents | `Promise<Array>` |
815
+ | `clear()` | Remove all documents | `Promise<void>` |
816
+ | `on(event, callback)` | Add event listener | `void` |
817
+ | `off(event, callback)` | Remove event listener | `void` |
818
+ | `clearCache()` | Clear query cache | `void` |
819
+
820
+ ## 💡 Examples
821
+
822
+ ### Todo Application
823
+
824
+ ```javascript
825
+ // Initialize
826
+ const lacerta = new LacertaDB();
827
+ const db = await lacerta.getDatabase('todoApp');
828
+ const todos = await db.createCollection('todos');
829
+
830
+ // Add todos
831
+ await todos.add({
832
+ title: 'Learn LacertaDB',
833
+ completed: false,
834
+ priority: 'high',
835
+ tags: ['learning', 'database'],
836
+ createdAt: Date.now()
837
+ });
838
+
839
+ // Query incomplete high-priority todos
840
+ const urgentTodos = await todos.query({
841
+ completed: false,
842
+ priority: 'high'
843
+ }, {
844
+ sort: { createdAt: -1 }
845
+ });
846
+
847
+ // Mark as complete
848
+ await todos.update(todoId, {
849
+ completed: true,
850
+ completedAt: Date.now()
851
+ });
852
+
853
+ // Get statistics
854
+ const stats = await todos.aggregate([
855
+ {
856
+ $group: {
857
+ _id: '$priority',
858
+ count: { $count: {} },
859
+ completed: {
860
+ $sum: { $cond: ['$completed', 1, 0] }
861
+ }
862
+ }
863
+ }
864
+ ]);
865
+ ```
866
+
867
+ ### E-Commerce Inventory
868
+
869
+ ```javascript
870
+ // Setup
871
+ const db = await lacerta.getDatabase('shop');
872
+ const products = await db.createCollection('products');
873
+ const orders = await db.createCollection('orders');
874
+
875
+ // Product with images
876
+ const productId = await products.add(
877
+ {
878
+ name: 'Wireless Mouse',
879
+ price: 29.99,
880
+ stock: 150,
881
+ category: 'electronics'
882
+ },
883
+ {
884
+ attachments: [productImage1, productImage2]
885
+ }
886
+ );
887
+
888
+ // Complex inventory query
889
+ const lowStock = await products.query({
890
+ $and: [
891
+ { stock: { $lt: 20 } },
892
+ { category: { $in: ['electronics', 'accessories'] } }
893
+ ]
894
+ }, {
895
+ projection: { name: 1, stock: 1, price: 1 }
896
+ });
897
+
898
+ // Sales report with joins
899
+ const salesReport = await orders.aggregate([
900
+ { $match: { status: 'completed' } },
901
+ {
902
+ $lookup: {
903
+ from: 'products',
904
+ localField: 'productId',
905
+ foreignField: '_id',
906
+ as: 'product'
907
+ }
908
+ },
909
+ {
910
+ $group: {
911
+ _id: '$product.category',
912
+ revenue: { $sum: '$total' },
913
+ orderCount: { $count: {} }
914
+ }
915
+ },
916
+ { $sort: { revenue: -1 } }
917
+ ]);
918
+ ```
919
+
920
+ ### User Session Management
921
+
922
+ ```javascript
923
+ // Encrypted session storage
924
+ const sessions = await db.createCollection('sessions');
925
+
926
+ // Store session with encryption
927
+ await sessions.add(
928
+ {
929
+ userId: 'user123',
930
+ token: 'secret-session-token',
931
+ ipAddress: '192.168.1.1',
932
+ userAgent: navigator.userAgent,
933
+ expiresAt: Date.now() + (24 * 60 * 60 * 1000)
934
+ },
935
+ {
936
+ encrypted: true,
937
+ password: process.env.SESSION_KEY,
938
+ permanent: false
939
+ }
940
+ );
941
+
942
+ // Cleanup expired sessions
943
+ const now = Date.now();
944
+ const expired = await sessions.query({
945
+ expiresAt: { $lt: now }
946
+ });
947
+
948
+ await sessions.batchDelete(expired.map(s => s._id));
949
+ ```
950
+
951
+ ## 🐛 Error Handling
952
+
953
+ LacertaDB provides detailed error information:
954
+
955
+ ```javascript
956
+ try {
957
+ await collection.get('non-existent-id');
958
+ } catch (error) {
959
+ if (error instanceof LacertaDBError) {
960
+ console.error('Error:', error.message);
961
+ console.error('Code:', error.code);
962
+ console.error('Timestamp:', error.timestamp);
963
+
964
+ // Handle specific error codes
965
+ switch(error.code) {
966
+ case 'DOCUMENT_NOT_FOUND':
967
+ // Handle missing document
968
+ break;
969
+ case 'ENCRYPTION_FAILED':
970
+ // Handle encryption error
971
+ break;
972
+ case 'QUOTA_EXCEEDED':
973
+ // Handle storage limit
974
+ break;
975
+ }
976
+ }
977
+ }
978
+ ```
979
+
980
+ ### Common Error Codes
981
+
982
+ | Code | Description | Solution |
983
+ |------|-------------|----------|
984
+ | `DOCUMENT_NOT_FOUND` | Document ID doesn't exist | Check ID or use query |
985
+ | `COLLECTION_NOT_FOUND` | Collection doesn't exist | Create collection first |
986
+ | `ENCRYPTION_FAILED` | Encryption/decryption error | Check password |
987
+ | `COMPRESSION_FAILED` | Compression error | Check data format |
988
+ | `QUOTA_EXCEEDED` | Storage limit reached | Increase limit or cleanup |
989
+ | `INVALID_OPERATION` | Operation not allowed | Check document flags |
990
+ | `TRANSACTION_FAILED` | Database transaction error | Retry operation |
991
+
992
+ ## 📝 Best Practices
993
+
994
+ ### 1. Index Strategy
995
+
996
+ ```javascript
997
+ // Analyze query patterns first
998
+ const queryPatterns = {
999
+ byEmail: { email: 'user@example.com' }, // Hash index
1000
+ byAgeRange: { age: { $gte: 25, $lte: 35 } }, // B-Tree index
1001
+ byDescription: { $text: 'search terms' }, // Text index
1002
+ byLocation: { $near: { lat: 0, lng: 0 } } // Geo index
1003
+ };
1004
+
1005
+ // Create appropriate indexes
1006
+ await users.createIndex('email', { type: 'hash', unique: true });
1007
+ await users.createIndex('age', { type: 'btree' });
1008
+ await users.createIndex('bio', { type: 'text' });
1009
+ await users.createIndex('location', { type: 'geo' });
1010
+ ```
1011
+
1012
+ ### 2. Cache Optimization
1013
+
1014
+ ```javascript
1015
+ // Match cache strategy to access patterns
1016
+ const cacheStrategies = {
1017
+ // Frequently changing data - LRU with short TTL
1018
+ activeSessions: { type: 'lru', maxSize: 1000, ttl: 60000 },
1019
+
1020
+ // Hot data - LFU for keeping popular items
1021
+ trendingProducts: { type: 'lfu', maxSize: 500 },
1022
+
1023
+ // Time-sensitive - TTL only
1024
+ tempTokens: { type: 'ttl', ttl: 300000 },
1025
+
1026
+ // Sensitive data - No cache
1027
+ privateKeys: { type: 'none', enabled: false }
178
1028
  };
1029
+ ```
1030
+
1031
+ ### 3. Security Best Practices
179
1032
 
180
- // Add a document with the attachment
181
- const reportId = await db.collection('reports').add(
182
- { title: 'Q3 Report' },
183
- { attachments: [attachment] }
1033
+ ```javascript
1034
+ // For private keys and sensitive data
1035
+ const secureDb = await lacerta.getSecureDatabase(
1036
+ 'vault',
1037
+ SecureDatabaseEncryption.generateSecurePIN(12) // 12-digit secure PIN
184
1038
  );
185
1039
 
186
- // Retrieve the document and its attachments
187
- const report = await db.collection('reports').get(reportId, {
188
- includeAttachments: true
1040
+ // Always use additional authentication
1041
+ await secureDb.storePrivateKey('key-name', privateKey, userEmail);
1042
+
1043
+ // Regular PIN rotation
1044
+ const rotatePin = async () => {
1045
+ const newPin = SecureDatabaseEncryption.generateSecurePIN(12);
1046
+ await secureDb.changePin(currentPin, newPin);
1047
+ // Securely store newPin
1048
+ };
1049
+ ```
1050
+
1051
+ ### 4. Performance Optimization
1052
+
1053
+ ```javascript
1054
+ // Enable monitoring during development
1055
+ lacerta.performanceMonitor.startMonitoring();
1056
+
1057
+ // Test different strategies
1058
+ const testPerformance = async () => {
1059
+ // Test without index
1060
+ const start1 = Date.now();
1061
+ await collection.query({ field: 'value' });
1062
+ console.log('Without index:', Date.now() - start1);
1063
+
1064
+ // Create index
1065
+ await collection.createIndex('field', { type: 'hash' });
1066
+
1067
+ // Test with index
1068
+ const start2 = Date.now();
1069
+ await collection.query({ field: 'value' });
1070
+ console.log('With index:', Date.now() - start2);
1071
+ };
1072
+
1073
+ // Get optimization suggestions
1074
+ const tips = lacerta.performanceMonitor.getOptimizationTips();
1075
+ ```
1076
+
1077
+ ### 5. Storage Management
1078
+
1079
+ ```javascript
1080
+ // Set appropriate limits
1081
+ db.updateSettings({
1082
+ sizeLimitKB: 100000, // 100MB total
1083
+ bufferLimitKB: 80000, // Start cleanup at 80MB
1084
+ freeSpaceEvery: 300000 // Check every 5 minutes
189
1085
  });
190
1086
 
191
- console.log(report.data._attachments[0].name); // "readme.txt"
192
- const content = new TextDecoder().decode(report.data._attachments[0].data);
193
- console.log(content); // "This is the content of my file."
1087
+ // Mark critical documents as permanent
1088
+ await collection.add(importantData, { permanent: true });
1089
+
1090
+ // Regular maintenance
1091
+ const maintenance = async () => {
1092
+ const stats = db.getStats();
1093
+ if (stats.totalSizeKB > 90000) {
1094
+ // Cleanup old non-permanent documents
1095
+ await collection.freeSpace();
1096
+ }
1097
+ };
1098
+ ```
1099
+
1100
+ ## 🔄 Migration from v4.x
1101
+
1102
+ ### Breaking Changes
1103
+
1104
+ None! LacertaDB v5.0.0 is fully backward compatible. All v4.x code continues to work without modifications.
1105
+
1106
+ ### New Features to Adopt
1107
+
1108
+ ```javascript
1109
+ // v4.x code (still works)
1110
+ const collection = await db.createCollection('data');
1111
+ const results = await collection.query({ status: 'active' });
1112
+
1113
+ // v5.0.0 optimized code
1114
+ const collection = await db.createCollection('data');
1115
+
1116
+ // Add index for 50x faster queries
1117
+ await collection.createIndex('status', { type: 'hash' });
1118
+
1119
+ // Configure smart caching
1120
+ await collection.configureCacheStrategy({
1121
+ type: 'lru',
1122
+ maxSize: 500,
1123
+ ttl: 120000
1124
+ });
1125
+
1126
+ // Now queries are much faster
1127
+ const results = await collection.query({ status: 'active' });
1128
+ ```
1129
+
1130
+ ### Migration Checklist
1131
+
1132
+ 1. **Add Indexes** to frequently queried fields
1133
+ 2. **Configure Cache Strategies** based on access patterns
1134
+ 3. **Enable PIN encryption** for databases with sensitive data
1135
+ 4. **Update force delete** calls for permanent document management
1136
+ 5. **Monitor performance** to identify optimization opportunities
1137
+
1138
+ ```javascript
1139
+ // Complete migration example
1140
+ const migrate = async () => {
1141
+ // 1. Get existing database
1142
+ const db = await lacerta.getDatabase('myApp');
1143
+
1144
+ // 2. Add indexes to collections
1145
+ const users = await db.getCollection('users');
1146
+ await users.createIndex('email', { type: 'hash', unique: true });
1147
+ await users.createIndex('createdAt', { type: 'btree' });
1148
+
1149
+ // 3. Configure caching
1150
+ await users.configureCacheStrategy({
1151
+ type: 'lru',
1152
+ maxSize: 1000,
1153
+ ttl: 300000
1154
+ });
1155
+
1156
+ // 4. For sensitive data, create new secure database
1157
+ const secureDb = await lacerta.getSecureDatabase('secure', pin);
1158
+ // Migrate sensitive data to secure database
1159
+
1160
+ console.log('Migration complete!');
1161
+ };
1162
+ ```
1163
+
1164
+ ## 🤝 Contributing
1165
+
1166
+ We welcome contributions! Here's how you can help:
1167
+
1168
+ 1. **Report Bugs**: Open an issue with reproduction steps
1169
+ 2. **Suggest Features**: Share your ideas in discussions
1170
+ 3. **Improve Docs**: Fix typos or add examples
1171
+ 4. **Submit PRs**: Fork, code, test, and submit
1172
+
1173
+ ### Development Setup
1174
+
1175
+ ```bash
1176
+ # Clone repository
1177
+ git clone https://github.com/pixagram-blockchain/LacertaDB.git
1178
+ cd LacertaDB
1179
+
1180
+ # Install dependencies
1181
+ npm install
1182
+
1183
+ # Run tests
1184
+ npm test
1185
+
1186
+ # Build
1187
+ npm run build
1188
+ ```
1189
+
1190
+ ### Testing
1191
+
1192
+ ```javascript
1193
+ // Test your changes
1194
+ import { LacertaDB } from './lacertadb.js';
1195
+
1196
+ const runTests = async () => {
1197
+ const lacerta = new LacertaDB();
1198
+ const db = await lacerta.getDatabase('test');
1199
+
1200
+ // Test new features
1201
+ const collection = await db.createCollection('test');
1202
+ await collection.createIndex('field', { type: 'hash' });
1203
+
1204
+ // Verify functionality
1205
+ console.assert(collection.indexManager.indexes.size === 1);
1206
+
1207
+ console.log('Tests passed!');
1208
+ };
1209
+ ```
1210
+
1211
+ ## 📄 License
1212
+
1213
+ MIT License - See [LICENSE](LICENSE) file for details
1214
+
1215
+ ## 🙏 Acknowledgments
1216
+
1217
+ - Built with ❤️ by the Pixagram team
1218
+ - Uses TurboSerial and TurboBase64 for high performance
1219
+ - Inspired by MongoDB's query language
1220
+ - Powered by modern browser APIs (IndexedDB, OPFS, Web Crypto)
194
1221
 
195
- ⚙️ Serialization: TurboSerial
196
- A key performance feature of LacertaDB is its use of turboserial instead of JSON. This provides several advantages:
1222
+ ## 📮 Support
197
1223
 
198
- Speed: turboserial is significantly faster at serializing and deserializing complex JavaScript objects.
1224
+ - 📧 Email: support@pixagram.com
1225
+ - 💬 Discord: [Join our community](https://discord.gg/pixagram)
1226
+ - 📚 Documentation: [docs.lacertadb.com](https://docs.lacertadb.com)
1227
+ - 🐛 Issues: [GitHub Issues](https://github.com/pixagram-blockchain/LacertaDB/issues)
199
1228
 
200
- 📦 Efficiency: It produces a more compact binary output, especially when compression is enabled, saving storage space.
1229
+ ## 🎉 What's New in v5.0.0
201
1230
 
202
- 🔬 Type Support: It correctly handles more data types than JSON, including Date, Map, Set, BigInt, and typed arrays.
1231
+ - **Custom Indexing**: B-Tree, Hash, Text, and Geo indexes for 50x faster queries
1232
+ - 🧠 **Smart Caching**: LRU, LFU, and TTL strategies with per-collection configuration
1233
+ - 🔐 **Database Encryption**: PIN-based security with 1M PBKDF2 iterations for private keys
1234
+ - 💪 **Force Delete**: Administrative control over permanent documents
1235
+ - 📊 **Enhanced Monitoring**: Detailed performance metrics and optimization tips
203
1236
 
204
- All data stored in localStorage (like metadata) or passed to IndexedDB is processed through turboserial and turbobase64, ensuring top-tier performance.
1237
+ ---
205
1238
 
206
- 📜 License
207
- LacertaDB is licensed under the MIT License.
1239
+ <div align="center">
1240
+ <strong>🦎 LacertaDB v5.0.0 - Fast, Secure, Browser-Native Database</strong>
1241
+ <br>
1242
+ <i>50x faster queries • Military-grade encryption • Smart caching</i>
1243
+ <br><br>
1244
+ Made with ❤️ by Pixagram Blockchain
1245
+ </div>