jexidb 2.0.2 → 2.0.3

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/docs/API.md ADDED
@@ -0,0 +1,390 @@
1
+ # JexiDB API Reference
2
+
3
+ ## Overview
4
+
5
+ JexiDB is a high-performance, local JSONL database with intelligent optimizations, real compression, and comprehensive error handling.
6
+
7
+ ## Core Classes
8
+
9
+ ### Database
10
+
11
+ The main database class that provides CRUD operations with intelligent optimizations.
12
+
13
+ #### Constructor
14
+
15
+ ```javascript
16
+ new Database(filePath, options = {})
17
+ ```
18
+
19
+ **Parameters:**
20
+ - `filePath` (string): Path to the database file
21
+ - `options` (object): Configuration options
22
+ - `indexes` (object): Index configuration
23
+ - `markDeleted` (boolean): Mark records as deleted instead of physical removal
24
+ - `create` (boolean): Create database if it doesn't exist (default: true)
25
+ - `clear` (boolean): Clear database on load if not empty (default: false)
26
+
27
+ **Auto-Save Configuration:**
28
+ - `autoSave` (boolean): Enable intelligent auto-save (default: true)
29
+ - `autoSaveThreshold` (number): Flush buffer when it reaches this many records (default: 50)
30
+ - `autoSaveInterval` (number): Flush buffer every N milliseconds (default: 5000)
31
+ - `forceSaveOnClose` (boolean): Always save when closing database (default: true)
32
+
33
+ **Performance Configuration:**
34
+ - `batchSize` (number): Batch size for inserts (default: 50)
35
+ - `adaptiveBatchSize` (boolean): Adjust batch size based on usage (default: true)
36
+ - `minBatchSize` (number): Minimum batch size for flush (default: 10)
37
+ - `maxBatchSize` (number): Maximum batch size for performance (default: 200)
38
+
39
+ **Memory Management:**
40
+ - `maxMemoryUsage` (string|number): Memory limit ('auto' or bytes, default: 'auto')
41
+ - `maxFlushChunkBytes` (number): Maximum chunk size for flush operations (default: 8MB)
42
+
43
+ #### Methods
44
+
45
+ ##### init()
46
+ Initializes the database and loads existing data.
47
+
48
+ ```javascript
49
+ await db.init()
50
+ ```
51
+
52
+ ##### insert(data)
53
+ Inserts a single record with adaptive optimization.
54
+
55
+ ```javascript
56
+ const record = await db.insert({ id: '1', name: 'John' })
57
+ ```
58
+
59
+ ##### insertMany(dataArray)
60
+ Inserts multiple records with bulk optimization.
61
+
62
+ ```javascript
63
+ const records = await db.insertMany([
64
+ { id: '1', name: 'John' },
65
+ { id: '2', name: 'Jane' }
66
+ ])
67
+ ```
68
+
69
+ ##### find(criteria, options)
70
+ Finds records matching criteria with query optimization.
71
+
72
+ ```javascript
73
+ const results = await db.find(
74
+ { age: { $gte: 25 } },
75
+ { limit: 10, sort: { name: 1 } }
76
+ )
77
+ ```
78
+
79
+ ##### findOne(criteria, options)
80
+ Finds a single record matching criteria.
81
+
82
+ ```javascript
83
+ const user = await db.findOne({ id: '1' })
84
+ ```
85
+
86
+ ##### update(criteria, updates, options)
87
+ Updates records matching criteria.
88
+
89
+ ```javascript
90
+ const updated = await db.update(
91
+ { id: '1' },
92
+ { name: 'John Updated', age: 30 }
93
+ )
94
+ ```
95
+
96
+ ##### delete(criteria, options)
97
+ Deletes records matching criteria.
98
+
99
+ ```javascript
100
+ const deleted = await db.delete({ id: '1' })
101
+ ```
102
+
103
+ ##### count(criteria)
104
+ Counts records matching criteria.
105
+
106
+ ```javascript
107
+ const count = await db.count({ active: true })
108
+ ```
109
+
110
+ ##### save()
111
+ Saves pending changes to disk.
112
+
113
+ ```javascript
114
+ await db.save()
115
+ ```
116
+
117
+ ##### flush()
118
+ Flushes the insertion buffer to disk immediately.
119
+
120
+ ```javascript
121
+ const flushedCount = await db.flush()
122
+ // Returns: number of records flushed
123
+ ```
124
+
125
+ ##### forceSave()
126
+ Forces a save operation regardless of buffer size.
127
+
128
+ ```javascript
129
+ await db.forceSave()
130
+ // Always saves, even with just 1 record in buffer
131
+ ```
132
+
133
+ ##### getBufferStatus()
134
+ Gets information about the current buffer state.
135
+
136
+ ```javascript
137
+ const status = db.getBufferStatus()
138
+ // Returns: {
139
+ // pendingCount: 15,
140
+ // bufferSize: 50,
141
+ // lastFlush: 1640995200000,
142
+ // lastAutoSave: 1640995200000,
143
+ // shouldFlush: false,
144
+ // autoSaveEnabled: true,
145
+ // autoSaveTimer: 'active'
146
+ // }
147
+ ```
148
+
149
+ ##### configurePerformance(settings)
150
+ Dynamically configures performance settings.
151
+
152
+ ```javascript
153
+ db.configurePerformance({
154
+ batchSize: 25,
155
+ autoSaveThreshold: 30,
156
+ autoSaveInterval: 4000
157
+ })
158
+ ```
159
+
160
+ ##### getPerformanceConfig()
161
+ Gets current performance configuration.
162
+
163
+ ```javascript
164
+ const config = db.getPerformanceConfig()
165
+ // Returns: {
166
+ // batchSize: 25,
167
+ // autoSaveThreshold: 30,
168
+ // autoSaveInterval: 4000,
169
+ // adaptiveBatchSize: true,
170
+ // minBatchSize: 10,
171
+ // maxBatchSize: 200
172
+ // }
173
+ ```
174
+
175
+ ##### validateIntegrity(options)
176
+ Validates database integrity.
177
+
178
+ ```javascript
179
+ const integrity = await db.validateIntegrity({ verbose: true })
180
+ ```
181
+
182
+ ##### getStats()
183
+ Gets comprehensive database statistics.
184
+
185
+ ```javascript
186
+ const stats = await db.getStats()
187
+ ```
188
+
189
+ ##### readColumnIndex(column)
190
+ Gets unique values from a specific column (indexed columns only).
191
+
192
+ ```javascript
193
+ const categories = db.readColumnIndex('category')
194
+ // Returns: Set(['Electronics', 'Books', 'Clothing'])
195
+ // Throws error for non-indexed columns
196
+ ```
197
+
198
+ ##### close()
199
+ Closes the database instance and saves pending changes.
200
+
201
+ ```javascript
202
+ await db.close()
203
+ // Saves data and closes instance, but keeps the database file
204
+ ```
205
+
206
+ ##### destroy()
207
+ Closes the database instance and saves pending changes (equivalent to close()).
208
+
209
+ ```javascript
210
+ await db.destroy()
211
+ // Same as: await db.close()
212
+ ```
213
+
214
+ ##### deleteDatabase()
215
+ **⚠️ WARNING: This permanently deletes the database file!**
216
+
217
+ Deletes the database file from disk and closes the instance.
218
+
219
+ ```javascript
220
+ await db.deleteDatabase() // Deletes the database file permanently
221
+ ```
222
+
223
+ ##### removeDatabase()
224
+ Removes the database file from disk (alias for deleteDatabase).
225
+
226
+ ```javascript
227
+ await db.removeDatabase() // Same as: await db.deleteDatabase()
228
+ ```
229
+
230
+ #### Properties
231
+
232
+ - `length`: Number of records in the database
233
+ - `indexStats`: Statistics about database indexes
234
+
235
+ #### Events
236
+
237
+ - `init`: Emitted when database is initialized
238
+ - `insert`: Emitted when a record is inserted
239
+ - `update`: Emitted when records are updated
240
+ - `delete`: Emitted when records are deleted
241
+ - `save`: Emitted when database is saved
242
+ - `before-save`: Emitted before database is saved
243
+
244
+ **Auto-Save Events:**
245
+ - `buffer-flush`: Emitted when buffer is flushed (count parameter)
246
+ - `buffer-full`: Emitted when buffer reaches threshold
247
+ - `auto-save-timer`: Emitted when time-based auto-save triggers
248
+ - `save-complete`: Emitted when save operation completes
249
+ - `close-save-complete`: Emitted when database closes with final save
250
+ - `close`: Emitted when database is closed
251
+ - `performance-configured`: Emitted when performance settings are changed
252
+
253
+ ### Query Operators
254
+
255
+ The database supports MongoDB-style query operators:
256
+
257
+ - `$eq`: Equal to
258
+ - `$ne`: Not equal to
259
+ - `$gt`: Greater than
260
+ - `$gte`: Greater than or equal to
261
+ - `$lt`: Less than
262
+ - `$lte`: Less than or equal to
263
+ - `$in`: In array
264
+ - `$nin`: Not in array
265
+ - `$regex`: Regular expression match
266
+
267
+ ### Nested Field Queries
268
+
269
+ You can query nested fields using dot notation:
270
+
271
+ ```javascript
272
+ const results = await db.find({
273
+ 'metadata.preferences.theme': 'dark',
274
+ 'metadata.loginCount': { $gt: 10 }
275
+ })
276
+ ```
277
+
278
+ ### Query Options
279
+
280
+ - `limit`: Limit number of results
281
+ - `skip`: Skip number of results
282
+ - `sort`: Sort results by field
283
+ - `caseInsensitive`: Case-insensitive string matching
284
+
285
+ ## Auto-Save Intelligence
286
+
287
+ JexiDB features intelligent auto-save capabilities that automatically manage data persistence without manual intervention.
288
+
289
+ ### Auto-Save Modes
290
+
291
+ **Intelligent Auto-Save (Default):**
292
+ - Automatically flushes buffer when it reaches the threshold (default: 50 records)
293
+ - Automatically flushes buffer every N milliseconds (default: 5000ms)
294
+ - Always saves when closing the database
295
+ - Provides real-time feedback through events
296
+
297
+ **Manual Mode:**
298
+ - Disable auto-save with `autoSave: false`
299
+ - Manually call `flush()` and `save()` when needed
300
+ - Useful for applications requiring precise control over persistence timing
301
+
302
+ ### Auto-Save Configuration
303
+
304
+ ```javascript
305
+ const db = new Database('data.jdb', {
306
+ // Enable intelligent auto-save
307
+ autoSave: true,
308
+ autoSaveThreshold: 50, // Flush every 50 records
309
+ autoSaveInterval: 5000, // Flush every 5 seconds
310
+ forceSaveOnClose: true, // Always save on close
311
+
312
+ // Performance tuning
313
+ batchSize: 50, // Reduced for faster response
314
+ adaptiveBatchSize: true, // Adjust based on usage
315
+ minBatchSize: 10, // Minimum flush size
316
+ maxBatchSize: 200 // Maximum flush size
317
+ });
318
+ ```
319
+
320
+ ### Event-Driven Monitoring
321
+
322
+ ```javascript
323
+ // Monitor auto-save operations
324
+ db.on('buffer-flush', (count) => {
325
+ console.log(`Flushed ${count} records`);
326
+ });
327
+
328
+ db.on('buffer-full', () => {
329
+ console.log('Buffer reached threshold');
330
+ });
331
+
332
+ db.on('auto-save-timer', () => {
333
+ console.log('Time-based auto-save triggered');
334
+ });
335
+
336
+ db.on('save-complete', () => {
337
+ console.log('Database saved successfully');
338
+ });
339
+ ```
340
+
341
+ ### Buffer Status Monitoring
342
+
343
+ ```javascript
344
+ // Check buffer status anytime
345
+ const status = db.getBufferStatus();
346
+ console.log(`Pending: ${status.pendingCount}/${status.bufferSize}`);
347
+ console.log(`Should flush: ${status.shouldFlush}`);
348
+ console.log(`Auto-save enabled: ${status.autoSaveEnabled}`);
349
+ ```
350
+
351
+ ## Optimization Features
352
+
353
+ ### Adaptive Mode Switching
354
+
355
+ JexiDB automatically switches between insertion and query optimization modes based on usage patterns.
356
+
357
+ ### Real Compression
358
+
359
+ - **LZ4**: Fast compression for warm data
360
+ - **Gzip**: High compression for cold data
361
+ - **Automatic fallback**: Graceful degradation if compression fails
362
+
363
+ ### Intelligent Caching
364
+
365
+ - **Query result caching**: Caches frequently accessed query results
366
+ - **Index caching**: Caches index data for faster lookups
367
+ - **Adaptive eviction**: Automatically manages cache size
368
+
369
+ ### Background Maintenance
370
+
371
+ - **Automatic compression**: Compresses old data in the background
372
+ - **Index optimization**: Optimizes indexes during idle time
373
+ - **Integrity checks**: Performs periodic integrity validation
374
+
375
+ ## Error Handling
376
+
377
+ Comprehensive error handling with automatic recovery:
378
+
379
+ - **File corruption recovery**: Repairs corrupted files
380
+ - **Index rebuilding**: Automatically rebuilds corrupted indexes
381
+ - **Memory pressure management**: Handles memory pressure gracefully
382
+ - **Compression fallback**: Falls back to no compression if needed
383
+
384
+ ## Performance Characteristics
385
+
386
+ - **Insert**: ~10,000 ops/sec (bulk), ~1,000 ops/sec (single)
387
+ - **Query**: ~5,000 ops/sec (indexed), ~500 ops/sec (unindexed)
388
+ - **Update**: ~1,000 ops/sec
389
+ - **Delete**: ~1,000 ops/sec
390
+ - **Compression**: 20-80% size reduction depending on data type
@@ -0,0 +1,177 @@
1
+ # Database Usage Examples
2
+
3
+ ## Basic Usage
4
+
5
+ ### Simple Database
6
+
7
+ ```javascript
8
+ const Database = require('jexidb');
9
+
10
+ // Create database
11
+ const db = new Database('./data/users.jsonl');
12
+
13
+ // Initialize
14
+ await db.init();
15
+
16
+ // Insert data
17
+ await db.insert({ id: '1', name: 'John', age: 30 });
18
+ await db.insert({ id: '2', name: 'Jane', age: 25 });
19
+
20
+ // Find data
21
+ const users = await db.find({ age: { $gte: 25 } });
22
+ const user = await db.findOne({ id: '1' });
23
+
24
+ // Update data
25
+ await db.update({ id: '1' }, { age: 31 });
26
+
27
+ // Delete data
28
+ await db.delete({ id: '2' });
29
+
30
+ // Save changes
31
+ await db.save();
32
+
33
+ // Clean up
34
+ await db.destroy();
35
+ ```
36
+
37
+ ### With Indexes
38
+
39
+ ```javascript
40
+ const db = new Database('./data/products.jsonl', {
41
+ indexes: {
42
+ id: true,
43
+ category: true,
44
+ price: true
45
+ }
46
+ });
47
+
48
+ await db.init();
49
+
50
+ // Fast indexed queries
51
+ const expensiveProducts = await db.find({ price: { $gt: 100 } });
52
+ const electronics = await db.find({ category: 'electronics' });
53
+ ```
54
+
55
+ ### Complex Queries
56
+
57
+ ```javascript
58
+ // Nested field queries
59
+ const activeUsers = await db.find({
60
+ 'metadata.active': true,
61
+ 'preferences.theme': 'dark',
62
+ age: { $gte: 18, $lte: 65 }
63
+ }, {
64
+ limit: 50,
65
+ sort: { 'metadata.lastLogin': -1 }
66
+ });
67
+
68
+ // Array queries
69
+ const taggedPosts = await db.find({
70
+ tags: { $in: ['javascript', 'database'] }
71
+ });
72
+
73
+ // Regular expressions
74
+ const emailUsers = await db.find({
75
+ email: { $regex: /@gmail\.com$/ }
76
+ });
77
+ ```
78
+
79
+ ### Bulk Operations
80
+
81
+ ```javascript
82
+ // Bulk insert
83
+ const users = Array.from({ length: 1000 }, (_, i) => ({
84
+ id: `user_${i}`,
85
+ name: `User ${i}`,
86
+ email: `user${i}@example.com`,
87
+ age: Math.floor(Math.random() * 50) + 18
88
+ }));
89
+
90
+ await db.insertMany(users);
91
+
92
+ // Bulk update
93
+ await db.update(
94
+ { age: { $lt: 18 } },
95
+ { status: 'minor' }
96
+ );
97
+
98
+ // Bulk delete
99
+ await db.delete({ status: 'inactive' });
100
+ ```
101
+
102
+ ### Event Handling
103
+
104
+ ```javascript
105
+ db.on('insert', (record, index) => {
106
+ console.log(`Inserted record at index ${index}`);
107
+ });
108
+
109
+ db.on('update', (records) => {
110
+ console.log(`Updated ${records.length} records`);
111
+ });
112
+
113
+ db.on('delete', (records) => {
114
+ console.log(`Deleted ${records.length} records`);
115
+ });
116
+
117
+ db.on('save', () => {
118
+ console.log('Database saved');
119
+ });
120
+ ```
121
+
122
+ ### Error Handling
123
+
124
+ ```javascript
125
+ try {
126
+ await db.insert(invalidData);
127
+ } catch (error) {
128
+ if (error.name === 'JexiDBError[JSON_PARSE_ERROR]') {
129
+ console.log('Invalid JSON data');
130
+ } else if (error.name === 'JexiDBError[FILE_CORRUPTION]') {
131
+ console.log('File corruption detected, attempting recovery...');
132
+ }
133
+ }
134
+ ```
135
+
136
+ ### Performance Monitoring
137
+
138
+ ```javascript
139
+ // Get database statistics
140
+ const stats = await db.getStats();
141
+ console.log(`Records: ${stats.recordCount}`);
142
+ console.log(`File size: ${stats.fileSize} bytes`);
143
+ console.log(`Cache hit rate: ${stats.cacheStats.hitRate}%`);
144
+
145
+ // Get optimization recommendations
146
+ const recommendations = db.getOptimizationRecommendations();
147
+ console.log('Optimization tips:', recommendations);
148
+ ```
149
+
150
+ ### Advanced Configuration
151
+
152
+ ```javascript
153
+ const db = new Database('./data/advanced.jsonl', {
154
+ indexes: {
155
+ id: true,
156
+ email: true,
157
+ 'metadata.created': true
158
+ },
159
+ markDeleted: false, // Physical deletion
160
+ autoSave: true,
161
+ validateOnInit: true,
162
+ backgroundMaintenance: true,
163
+ cache: {
164
+ maxSize: 1000,
165
+ ttl: 300000 // 5 minutes
166
+ },
167
+ compression: {
168
+ hot: { type: 'none', threshold: 7 },
169
+ warm: { type: 'lz4', threshold: 30 },
170
+ cold: { type: 'gzip', threshold: Infinity }
171
+ },
172
+ errorHandler: {
173
+ logLevel: 'info',
174
+ enableRecovery: true
175
+ }
176
+ });
177
+ ```