@pixagram/lacerta-db 0.3.0 โ 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/package.json +2 -2
- package/readme.md +1046 -131
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixagram/lacerta-db",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Lacerta-DB is a Javascript IndexedDB Database for Web Browsers. Simple, Fast, Secure.",
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@babel/core": "^7.23.6",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"license": "MIT",
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|
|
40
|
-
"url": ""
|
|
40
|
+
"url": "https://github.com/pixagram-blockchain/LacertaDB"
|
|
41
41
|
},
|
|
42
42
|
"engines": {
|
|
43
43
|
"node": ">=0.8.0"
|
package/readme.md
CHANGED
|
@@ -1,207 +1,1122 @@
|
|
|
1
|
-
LacertaDB
|
|
2
|
-
LacertaDB
|
|
1
|
+
# LacertaDB
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
> ๐ฆ **LacertaDB v4.0.3** - A powerful, feature-rich browser-based document database with encryption, compression, and advanced querying capabilities.
|
|
5
|
+
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[]()
|
|
8
|
+
[]()
|
|
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
|
+
});
|
|
3
84
|
|
|
4
|
-
|
|
85
|
+
// Query documents
|
|
86
|
+
const results = await users.query({
|
|
87
|
+
age: { $gte: 25 },
|
|
88
|
+
tags: { $in: ['developer'] }
|
|
89
|
+
});
|
|
5
90
|
|
|
6
|
-
|
|
7
|
-
|
|
91
|
+
console.log('Found users:', results);
|
|
92
|
+
```
|
|
8
93
|
|
|
9
|
-
|
|
94
|
+
## ๐ฆ Installation
|
|
10
95
|
|
|
11
|
-
|
|
96
|
+
### NPM/Yarn Installation
|
|
12
97
|
|
|
13
|
-
|
|
98
|
+
```bash
|
|
99
|
+
npm install @pixagram/lacertadb
|
|
100
|
+
# or
|
|
101
|
+
yarn add @pixagram/lacertadb
|
|
102
|
+
```
|
|
14
103
|
|
|
15
|
-
|
|
104
|
+
### Browser Module
|
|
16
105
|
|
|
17
|
-
|
|
106
|
+
```html
|
|
107
|
+
<script type="module">
|
|
108
|
+
import { LacertaDB } from './lacertadb.js';
|
|
109
|
+
const lacerta = new LacertaDB();
|
|
110
|
+
</script>
|
|
111
|
+
```
|
|
18
112
|
|
|
19
|
-
|
|
113
|
+
### Dependencies
|
|
20
114
|
|
|
21
|
-
|
|
115
|
+
LacertaDB requires:
|
|
116
|
+
- `@pixagram/turboserial` - High-performance serialization
|
|
117
|
+
- `@pixagram/turbobase64` - Optimized Base64 encoding
|
|
22
118
|
|
|
23
|
-
|
|
119
|
+
## ๐ฏ Basic Usage
|
|
24
120
|
|
|
25
|
-
|
|
26
|
-
Install the package using your favorite package manager.
|
|
121
|
+
### Creating a Database and Collection
|
|
27
122
|
|
|
28
|
-
|
|
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
|
+
```
|
|
161
|
+
|
|
162
|
+
### Retrieving Documents
|
|
163
|
+
|
|
164
|
+
```javascript
|
|
165
|
+
// Get by ID
|
|
166
|
+
const product = await products.get('custom-id-123', {
|
|
167
|
+
password: 'secretPassword' // Required for encrypted documents
|
|
168
|
+
});
|
|
29
169
|
|
|
30
|
-
|
|
31
|
-
|
|
170
|
+
// Get all documents
|
|
171
|
+
const allProducts = await products.getAll();
|
|
32
172
|
|
|
33
|
-
//
|
|
34
|
-
|
|
173
|
+
// Get with attachments
|
|
174
|
+
const withFiles = await products.get('doc-id', {
|
|
175
|
+
includeAttachments: true
|
|
176
|
+
});
|
|
177
|
+
```
|
|
35
178
|
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
// 1. Get a database instance
|
|
39
|
-
const db = await LacertaDB.getDatabase('my-app-db');
|
|
179
|
+
## ๐ง Core Concepts
|
|
40
180
|
|
|
41
|
-
|
|
42
|
-
// Collections are created automatically on first access
|
|
43
|
-
const users = await db.getCollection('users');
|
|
181
|
+
### Database
|
|
44
182
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
183
|
+
The database is the top-level container for your collections.
|
|
184
|
+
|
|
185
|
+
```javascript
|
|
186
|
+
// Get existing or create new database
|
|
187
|
+
const db = await lacerta.getDatabase('appDB');
|
|
188
|
+
|
|
189
|
+
// List all collections
|
|
190
|
+
const collections = db.listCollections();
|
|
191
|
+
|
|
192
|
+
// Get database statistics
|
|
193
|
+
const stats = db.getStats();
|
|
194
|
+
console.log(`Total size: ${stats.totalSizeKB} KB`);
|
|
195
|
+
console.log(`Total documents: ${stats.totalDocuments}`);
|
|
196
|
+
|
|
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
|
+
```
|
|
52
204
|
|
|
53
|
-
|
|
54
|
-
const user = await users.get(newUserId);
|
|
55
|
-
console.log('Retrieved user:', user);
|
|
205
|
+
### Collections
|
|
56
206
|
|
|
57
|
-
|
|
58
|
-
const highLevelUsers = await users.query({ level: { '$gt': 5 } });
|
|
59
|
-
console.log('High-level users:', highLevelUsers);
|
|
207
|
+
Collections are containers for documents of similar type.
|
|
60
208
|
|
|
61
|
-
|
|
62
|
-
|
|
209
|
+
```javascript
|
|
210
|
+
// Create collection
|
|
211
|
+
const posts = await db.createCollection('posts');
|
|
212
|
+
|
|
213
|
+
// Get existing collection
|
|
214
|
+
const existingPosts = await db.getCollection('posts');
|
|
215
|
+
|
|
216
|
+
// Collection operations
|
|
217
|
+
await posts.clear(); // Remove all documents
|
|
218
|
+
await db.dropCollection('posts'); // Delete collection entirely
|
|
219
|
+
|
|
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
|
+
```
|
|
244
|
+
|
|
245
|
+
## ๐ Querying
|
|
246
|
+
|
|
247
|
+
### Basic Queries
|
|
248
|
+
|
|
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
|
+
});
|
|
255
|
+
|
|
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
|
-
|
|
272
|
+
### Advanced Queries
|
|
67
273
|
|
|
68
|
-
|
|
69
|
-
Database
|
|
70
|
-
The Database object is your main entry point for managing collections.
|
|
274
|
+
LacertaDB supports MongoDB-style query operators:
|
|
71
275
|
|
|
72
|
-
|
|
73
|
-
Retrieves a database instance. If it doesn't exist, it's created.
|
|
276
|
+
#### Comparison Operators
|
|
74
277
|
|
|
75
|
-
|
|
278
|
+
```javascript
|
|
279
|
+
// $eq, $ne, $gt, $gte, $lt, $lte
|
|
280
|
+
await products.query({
|
|
281
|
+
price: { $gte: 100, $lte: 500 }
|
|
282
|
+
});
|
|
76
283
|
|
|
77
|
-
|
|
78
|
-
|
|
284
|
+
// $in, $nin
|
|
285
|
+
await users.query({
|
|
286
|
+
role: { $in: ['admin', 'moderator'] }
|
|
287
|
+
});
|
|
288
|
+
```
|
|
79
289
|
|
|
80
|
-
|
|
290
|
+
#### Logical Operators
|
|
81
291
|
|
|
82
|
-
|
|
83
|
-
|
|
292
|
+
```javascript
|
|
293
|
+
// $and
|
|
294
|
+
await products.query({
|
|
295
|
+
$and: [
|
|
296
|
+
{ price: { $lt: 1000 } },
|
|
297
|
+
{ category: 'electronics' }
|
|
298
|
+
]
|
|
299
|
+
});
|
|
84
300
|
|
|
85
|
-
|
|
301
|
+
// $or
|
|
302
|
+
await users.query({
|
|
303
|
+
$or: [
|
|
304
|
+
{ age: { $gte: 65 } },
|
|
305
|
+
{ status: 'premium' }
|
|
306
|
+
]
|
|
307
|
+
});
|
|
86
308
|
|
|
87
|
-
|
|
88
|
-
|
|
309
|
+
// $not
|
|
310
|
+
await products.query({
|
|
311
|
+
discontinued: { $not: { $eq: true } }
|
|
312
|
+
});
|
|
313
|
+
```
|
|
89
314
|
|
|
90
|
-
|
|
91
|
-
Adds a new document to the collection.
|
|
315
|
+
#### Array Operators
|
|
92
316
|
|
|
93
|
-
|
|
317
|
+
```javascript
|
|
318
|
+
// $all - Array contains all values
|
|
319
|
+
await posts.query({
|
|
320
|
+
tags: { $all: ['javascript', 'database'] }
|
|
321
|
+
});
|
|
94
322
|
|
|
95
|
-
|
|
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
|
-
|
|
333
|
+
// $size - Array length
|
|
334
|
+
await users.query({
|
|
335
|
+
hobbies: { $size: 3 }
|
|
336
|
+
});
|
|
337
|
+
```
|
|
98
338
|
|
|
99
|
-
|
|
339
|
+
#### Text Search
|
|
100
340
|
|
|
101
|
-
|
|
341
|
+
```javascript
|
|
342
|
+
// $regex - Regular expression
|
|
343
|
+
await users.query({
|
|
344
|
+
email: { $regex: '@company\\.com$' }
|
|
345
|
+
});
|
|
102
346
|
|
|
103
|
-
|
|
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
|
-
|
|
430
|
+
// Retrieve encrypted document
|
|
431
|
+
const userData = await users.get('user-id', {
|
|
432
|
+
password: 'strong-password-here' // Required for decryption
|
|
433
|
+
});
|
|
106
434
|
|
|
107
|
-
|
|
108
|
-
|
|
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
|
-
|
|
445
|
+
### Password Protection
|
|
111
446
|
|
|
112
|
-
|
|
447
|
+
Secure your exports and backups:
|
|
113
448
|
|
|
114
|
-
|
|
449
|
+
```javascript
|
|
450
|
+
// Export with encryption
|
|
451
|
+
const encryptedExport = await db.export('encrypted', 'export-password');
|
|
115
452
|
|
|
116
|
-
|
|
453
|
+
// Import encrypted data
|
|
454
|
+
await db.import(encryptedExport, 'encrypted', 'export-password');
|
|
117
455
|
|
|
118
|
-
|
|
456
|
+
// Create encrypted backup
|
|
457
|
+
const backup = await lacerta.createBackup('backup-password');
|
|
119
458
|
|
|
120
|
-
|
|
121
|
-
|
|
459
|
+
// Restore from encrypted backup
|
|
460
|
+
await lacerta.restoreBackup(backup, 'backup-password');
|
|
461
|
+
```
|
|
122
462
|
|
|
123
|
-
|
|
463
|
+
## ๐ Attachments
|
|
124
464
|
|
|
125
|
-
|
|
465
|
+
Store files using the Origin Private File System:
|
|
126
466
|
|
|
127
|
-
|
|
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
|
-
|
|
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
|
+
);
|
|
487
|
+
|
|
488
|
+
// Retrieve with attachments
|
|
489
|
+
const docWithFiles = await documents.get(docId, {
|
|
490
|
+
includeAttachments: true
|
|
491
|
+
});
|
|
130
492
|
|
|
131
|
-
|
|
493
|
+
// Access attachments
|
|
494
|
+
docWithFiles._attachments.forEach(attachment => {
|
|
495
|
+
console.log(`File: ${attachment.name} (${attachment.size} bytes)`);
|
|
496
|
+
// attachment.data is Uint8Array
|
|
497
|
+
});
|
|
498
|
+
```
|
|
132
499
|
|
|
133
|
-
|
|
500
|
+
## โก Performance
|
|
134
501
|
|
|
135
|
-
|
|
136
|
-
Updates the data of a specific document.
|
|
502
|
+
### Compression
|
|
137
503
|
|
|
138
|
-
|
|
504
|
+
Reduce storage size with automatic compression:
|
|
139
505
|
|
|
140
|
-
|
|
141
|
-
|
|
506
|
+
```javascript
|
|
507
|
+
// Enable compression for all documents in collection
|
|
508
|
+
const compressedColl = await db.createCollection('largeDocs', {
|
|
509
|
+
compressed: true
|
|
510
|
+
});
|
|
142
511
|
|
|
143
|
-
|
|
512
|
+
// Per-document compression
|
|
513
|
+
await collection.add(largeData, {
|
|
514
|
+
compressed: true // Uses DeflateStream compression
|
|
515
|
+
});
|
|
516
|
+
```
|
|
144
517
|
|
|
145
|
-
|
|
146
|
-
Processes documents through an aggregation pipeline.
|
|
518
|
+
### Performance Monitoring
|
|
147
519
|
|
|
148
|
-
|
|
149
|
-
{ '$match': { level: { '$gt': 5 } } },
|
|
150
|
-
{ '$group': { _id: null, averageLevel: { '$avg': '$level' } } }
|
|
151
|
-
]);
|
|
520
|
+
Track database performance metrics:
|
|
152
521
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
522
|
+
```javascript
|
|
523
|
+
// Start monitoring
|
|
524
|
+
lacerta.performanceMonitor.startMonitoring();
|
|
156
525
|
|
|
157
|
-
|
|
526
|
+
// Perform operations...
|
|
158
527
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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:
|
|
546
|
+
|
|
547
|
+
```javascript
|
|
548
|
+
// First query - hits database
|
|
549
|
+
const results1 = await users.query({ status: 'active' });
|
|
550
|
+
|
|
551
|
+
// Second identical query - served from cache
|
|
552
|
+
const results2 = await users.query({ status: 'active' });
|
|
553
|
+
|
|
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
|
-
//
|
|
165
|
-
|
|
166
|
-
|
|
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
|
-
|
|
170
|
-
|
|
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
|
-
//
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
+
});
|
|
179
852
|
|
|
180
|
-
//
|
|
181
|
-
const
|
|
182
|
-
{
|
|
183
|
-
|
|
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
|
+
}
|
|
184
886
|
);
|
|
185
887
|
|
|
186
|
-
//
|
|
187
|
-
const
|
|
188
|
-
|
|
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. ๐ฏ Design Your Schema
|
|
995
|
+
|
|
996
|
+
```javascript
|
|
997
|
+
// Good: Consistent document structure
|
|
998
|
+
const userSchema = {
|
|
999
|
+
type: 'user',
|
|
1000
|
+
email: '',
|
|
1001
|
+
profile: {
|
|
1002
|
+
name: '',
|
|
1003
|
+
avatar: '',
|
|
1004
|
+
bio: ''
|
|
1005
|
+
},
|
|
1006
|
+
settings: {},
|
|
1007
|
+
metadata: {
|
|
1008
|
+
createdAt: Date.now(),
|
|
1009
|
+
lastLogin: null
|
|
1010
|
+
}
|
|
1011
|
+
};
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
### 2. ๐ Index Planning
|
|
1015
|
+
|
|
1016
|
+
```javascript
|
|
1017
|
+
// Create indexes for frequently queried fields
|
|
1018
|
+
// (Indexes are automatically created for _id and _modified)
|
|
1019
|
+
// For custom indexes, use query patterns to identify needs
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
### 3. ๐ Security First
|
|
1023
|
+
|
|
1024
|
+
```javascript
|
|
1025
|
+
// Always encrypt sensitive data
|
|
1026
|
+
const sensitiveOps = {
|
|
1027
|
+
encrypted: true,
|
|
1028
|
+
password: await generateSecurePassword(),
|
|
1029
|
+
permanent: true // Prevent accidental deletion
|
|
1030
|
+
};
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
### 4. โก Performance Optimization
|
|
1034
|
+
|
|
1035
|
+
```javascript
|
|
1036
|
+
// Use batch operations for bulk actions
|
|
1037
|
+
await collection.batchAdd(largeDataset, {
|
|
1038
|
+
compressed: true // Compress large datasets
|
|
189
1039
|
});
|
|
190
1040
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
1041
|
+
// Enable monitoring during development
|
|
1042
|
+
lacerta.performanceMonitor.startMonitoring();
|
|
1043
|
+
// ... test operations ...
|
|
1044
|
+
const tips = lacerta.performanceMonitor.getOptimizationTips();
|
|
1045
|
+
```
|
|
1046
|
+
|
|
1047
|
+
### 5. ๐งน Regular Maintenance
|
|
1048
|
+
|
|
1049
|
+
```javascript
|
|
1050
|
+
// Set appropriate limits
|
|
1051
|
+
db.updateSettings({
|
|
1052
|
+
sizeLimitKB: 50000,
|
|
1053
|
+
bufferLimitKB: 40000,
|
|
1054
|
+
freeSpaceEvery: 300000 // 5 minutes
|
|
1055
|
+
});
|
|
1056
|
+
|
|
1057
|
+
// Regular backups
|
|
1058
|
+
const dailyBackup = async () => {
|
|
1059
|
+
const backup = await lacerta.createBackup('secure-password');
|
|
1060
|
+
await saveToCloud(backup);
|
|
1061
|
+
};
|
|
1062
|
+
setInterval(dailyBackup, 24 * 60 * 60 * 1000);
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
### 6. ๐ Monitor Usage
|
|
1066
|
+
|
|
1067
|
+
```javascript
|
|
1068
|
+
// Track database growth
|
|
1069
|
+
const monitor = async () => {
|
|
1070
|
+
const stats = db.getStats();
|
|
1071
|
+
if (stats.totalSizeKB > 40000) {
|
|
1072
|
+
console.warn('Database size exceeds 40MB');
|
|
1073
|
+
// Trigger cleanup or alert
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
## ๐ค Contributing
|
|
1079
|
+
|
|
1080
|
+
We welcome contributions! Here's how you can help:
|
|
1081
|
+
|
|
1082
|
+
1. ๐ **Report Bugs**: Open an issue with reproduction steps
|
|
1083
|
+
2. ๐ก **Suggest Features**: Share your ideas in discussions
|
|
1084
|
+
3. ๐ **Improve Docs**: Fix typos or add examples
|
|
1085
|
+
4. ๐ง **Submit PRs**: Fork, code, test, and submit
|
|
1086
|
+
|
|
1087
|
+
### Development Setup
|
|
1088
|
+
|
|
1089
|
+
```bash
|
|
1090
|
+
# Clone repository
|
|
1091
|
+
git clone https://github.com/pixagram-blockchain/LacertaDB.git
|
|
1092
|
+
cd LacertaDB
|
|
1093
|
+
|
|
1094
|
+
# Install dependencies
|
|
1095
|
+
npm install @pixagram/lacerta-db
|
|
1096
|
+
|
|
1097
|
+
# Run tests
|
|
1098
|
+
npm test
|
|
1099
|
+
|
|
1100
|
+
# Build
|
|
1101
|
+
npm run build
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
## ๐ License
|
|
1105
|
+
|
|
1106
|
+
MIT License - See [LICENSE](LICENSE) file for details
|
|
194
1107
|
|
|
195
|
-
|
|
196
|
-
A key performance feature of LacertaDB is its use of turboserial instead of JSON. This provides several advantages:
|
|
1108
|
+
## ๐ Acknowledgments
|
|
197
1109
|
|
|
198
|
-
|
|
1110
|
+
- Built with โค๏ธ by the Pixagram team
|
|
1111
|
+
- Uses TurboSerial and TurboBase64 for high performance
|
|
1112
|
+
- Inspired by MongoDB's query language
|
|
1113
|
+
- Powered by modern browser APIs
|
|
199
1114
|
|
|
200
|
-
|
|
1115
|
+
## ๐ฎ Support
|
|
201
1116
|
|
|
202
|
-
|
|
1117
|
+
- ๐ง Email: omnibus (at) pixagram.io
|
|
1118
|
+
- ๐ Issues: [GitHub Issues](https://github.com/pixagram-blockchain/LacertaDB/issues)
|
|
203
1119
|
|
|
204
|
-
|
|
1120
|
+
---
|
|
205
1121
|
|
|
206
|
-
|
|
207
|
-
LacertaDB is licensed under the MIT License.
|
|
1122
|
+
๐ฆ LacertaDB - Fast, Secure, Browser-Native Database
|