jexidb 2.0.2 → 2.1.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.
Files changed (55) hide show
  1. package/.babelrc +13 -0
  2. package/.gitattributes +2 -0
  3. package/CHANGELOG.md +140 -0
  4. package/LICENSE +21 -21
  5. package/README.md +301 -527
  6. package/babel.config.json +5 -0
  7. package/dist/Database.cjs +3896 -0
  8. package/docs/API.md +1051 -0
  9. package/docs/EXAMPLES.md +701 -0
  10. package/docs/README.md +194 -0
  11. package/examples/iterate-usage-example.js +157 -0
  12. package/examples/simple-iterate-example.js +115 -0
  13. package/jest.config.js +24 -0
  14. package/package.json +63 -51
  15. package/scripts/README.md +47 -0
  16. package/scripts/clean-test-files.js +75 -0
  17. package/scripts/prepare.js +31 -0
  18. package/scripts/run-tests.js +80 -0
  19. package/src/Database.mjs +4130 -0
  20. package/src/FileHandler.mjs +1101 -0
  21. package/src/OperationQueue.mjs +279 -0
  22. package/src/SchemaManager.mjs +268 -0
  23. package/src/Serializer.mjs +511 -0
  24. package/src/managers/ConcurrencyManager.mjs +257 -0
  25. package/src/managers/IndexManager.mjs +1403 -0
  26. package/src/managers/QueryManager.mjs +1273 -0
  27. package/src/managers/StatisticsManager.mjs +262 -0
  28. package/src/managers/StreamingProcessor.mjs +429 -0
  29. package/src/managers/TermManager.mjs +278 -0
  30. package/test/$not-operator-with-and.test.js +282 -0
  31. package/test/README.md +8 -0
  32. package/test/close-init-cycle.test.js +256 -0
  33. package/test/critical-bugs-fixes.test.js +1069 -0
  34. package/test/index-persistence.test.js +306 -0
  35. package/test/index-serialization.test.js +314 -0
  36. package/test/indexed-query-mode.test.js +360 -0
  37. package/test/iterate-method.test.js +272 -0
  38. package/test/query-operators.test.js +238 -0
  39. package/test/regex-array-fields.test.js +129 -0
  40. package/test/score-method.test.js +238 -0
  41. package/test/setup.js +17 -0
  42. package/test/term-mapping-minimal.test.js +154 -0
  43. package/test/term-mapping-simple.test.js +257 -0
  44. package/test/term-mapping.test.js +514 -0
  45. package/test/writebuffer-flush-resilience.test.js +204 -0
  46. package/dist/FileHandler.js +0 -688
  47. package/dist/IndexManager.js +0 -353
  48. package/dist/IntegrityChecker.js +0 -364
  49. package/dist/JSONLDatabase.js +0 -1194
  50. package/dist/index.js +0 -617
  51. package/src/FileHandler.js +0 -674
  52. package/src/IndexManager.js +0 -363
  53. package/src/IntegrityChecker.js +0 -379
  54. package/src/JSONLDatabase.js +0 -1248
  55. package/src/index.js +0 -608
package/docs/README.md ADDED
@@ -0,0 +1,194 @@
1
+ # JexiDB Documentation
2
+
3
+ Welcome to the JexiDB documentation! This directory contains comprehensive guides and references for using JexiDB effectively.
4
+
5
+ ## 📚 Documentation Structure
6
+
7
+ ### 🚀 [API Reference](API.md)
8
+ Complete API documentation covering all methods, options, and features:
9
+ - Database constructor and configuration
10
+ - Core methods (insert, update, delete, find)
11
+ - Advanced features (term mapping, bulk operations)
12
+ - Query operators and complex queries
13
+ - Performance optimization tips
14
+
15
+ ### 💡 [Examples](EXAMPLES.md)
16
+ Practical examples and real-world use cases:
17
+ - Basic usage patterns
18
+ - User management systems
19
+ - Product catalogs
20
+ - Blog systems
21
+ - Analytics dashboards
22
+ - Performance optimization techniques
23
+ - Error handling strategies
24
+
25
+ ## 🎯 Quick Start
26
+
27
+ If you're new to JexiDB, start with these resources:
28
+
29
+ 1. **Installation**: See the main [README.md](../README.md) for installation instructions
30
+ 2. **Basic Usage**: Check out the [Basic Usage](EXAMPLES.md#basic-usage) section in Examples
31
+ 3. **API Reference**: Browse the [API Reference](API.md) for detailed method documentation
32
+ 4. **Advanced Features**: Explore [Term Mapping](API.md#term-mapping) and [Bulk Operations](API.md#bulk-operations)
33
+
34
+ ## 🔍 What's New
35
+
36
+ ### Recent Features
37
+ - **Term Mapping**: Reduce database size by up to 77% for repetitive data
38
+ - **Bulk Operations**: High-performance `iterate()` method for large datasets
39
+ - **Advanced Querying**: Support for complex queries with logical operators
40
+ - **Indexed Query Modes**: Strict and permissive query modes for performance control
41
+
42
+ ### Performance Improvements
43
+ - Streaming operations for memory efficiency
44
+ - Automatic term cleanup
45
+ - Optimized indexing strategies
46
+ - Batch processing capabilities
47
+
48
+ ## 📖 Key Concepts
49
+
50
+ ### Indexes
51
+ Define which fields to keep in memory for fast queries:
52
+ ```javascript
53
+ const db = new Database('app.jdb', {
54
+ fields: { // REQUIRED - Define schema
55
+ id: 'number',
56
+ name: 'string',
57
+ email: 'string'
58
+ },
59
+ indexes: { // OPTIONAL - Only fields you query frequently
60
+ email: 'string' // ✅ Login queries
61
+ }
62
+ })
63
+ ```
64
+
65
+ ### Term Mapping
66
+ Optimize storage for repetitive string data:
67
+ ```javascript
68
+ const db = new Database('app.jdb', {
69
+ fields: { // REQUIRED - Define schema
70
+ id: 'number',
71
+ name: 'string',
72
+ tags: 'array:string',
73
+ categories: 'array:string'
74
+ }
75
+ // termMapping is now auto-enabled for array:string fields
76
+ })
77
+ ```
78
+
79
+ ### Bulk Operations
80
+ Process large datasets efficiently:
81
+ ```javascript
82
+ for await (const record of db.iterate({ status: 'pending' })) {
83
+ record.status = 'processed'
84
+ record.updatedAt = Date.now()
85
+ }
86
+ ```
87
+
88
+ ## 🛠️ Common Patterns
89
+
90
+ ### Database Lifecycle
91
+ ```javascript
92
+ const db = new Database('my-app.jdb', options)
93
+ await db.init() // Initialize
94
+ // ... use database ...
95
+ await db.save() // Save changes
96
+ await db.destroy() // Clean up
97
+ ```
98
+
99
+ ### Error Handling
100
+ ```javascript
101
+ try {
102
+ await db.init()
103
+ await db.insert(data)
104
+ await db.save()
105
+ } catch (error) {
106
+ console.error('Database error:', error)
107
+ } finally {
108
+ await db.destroy()
109
+ }
110
+ ```
111
+
112
+ ### Query Patterns
113
+ ```javascript
114
+ // Simple queries
115
+ const users = await db.find({ status: 'active' })
116
+
117
+ // Complex queries
118
+ const results = await db.find({
119
+ age: { '>': 18, '<': 65 },
120
+ $or: [
121
+ { role: 'admin' },
122
+ { role: 'moderator' }
123
+ ]
124
+ })
125
+
126
+ // Case-insensitive search
127
+ const results = await db.find(
128
+ { name: 'john doe' },
129
+ { caseInsensitive: true }
130
+ )
131
+ ```
132
+
133
+ ## 🔧 Configuration Options
134
+
135
+ ### Basic Configuration
136
+ ```javascript
137
+ const db = new Database('database.jdb', {
138
+ create: true, // Create file if doesn't exist
139
+ clear: false, // Clear existing data
140
+ fields: { // REQUIRED - Define schema
141
+ id: 'number',
142
+ name: 'string'
143
+ },
144
+ indexes: { // OPTIONAL - Only fields you query frequently
145
+ name: 'string' // ✅ Search by name
146
+ },
147
+ indexedQueryMode: 'permissive' // Query mode
148
+ })
149
+ ```
150
+
151
+ ### Advanced Configuration
152
+ ```javascript
153
+ const db = new Database('database.jdb', {
154
+ fields: { // REQUIRED - Define schema
155
+ id: 'number',
156
+ name: 'string',
157
+ tags: 'array:string'
158
+ },
159
+ indexes: { // OPTIONAL - Only fields you query frequently
160
+ name: 'string', // ✅ Search by name
161
+ tags: 'array:string' // ✅ Search by tags
162
+ }
163
+ // termMapping is now auto-enabled for array:string fields
164
+ })
165
+ ```
166
+
167
+ ## 📊 Performance Tips
168
+
169
+ 1. **Use indexed fields** in your queries for best performance
170
+ 2. **Enable term mapping** for datasets with repetitive strings
171
+ 3. **Use `iterate()`** for bulk operations on large datasets
172
+ 4. **Specify fewer indexes** to reduce memory usage
173
+ 5. **Use `save()`** strategically to persist changes
174
+
175
+ ## 🆘 Getting Help
176
+
177
+ - **Issues**: Report bugs and request features on [GitHub Issues](https://github.com/EdenwareApps/jexidb/issues)
178
+ - **Documentation**: Browse this documentation for detailed guides
179
+ - **Examples**: Check out the [Examples](EXAMPLES.md) for practical use cases
180
+ - **API Reference**: Consult the [API Reference](API.md) for method details
181
+
182
+ ## 📝 Contributing
183
+
184
+ Found an issue with the documentation? Want to add an example?
185
+
186
+ 1. Fork the repository
187
+ 2. Make your changes
188
+ 3. Submit a pull request
189
+
190
+ We welcome contributions to improve the documentation!
191
+
192
+ ---
193
+
194
+ **Happy coding with JexiDB! 🚀**
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Example usage of the new iterate() method
3
+ * Demonstrates bulk update capabilities with streaming performance
4
+ */
5
+
6
+ import { Database } from '../src/Database.mjs'
7
+
8
+ async function demonstrateIterate() {
9
+ console.log('🚀 JexiDB iterate() Method Demo\n')
10
+
11
+ // Create database with indexing
12
+ const db = new Database('iterate-demo.jdb', {
13
+ debugMode: true,
14
+ termMapping: true,
15
+ indexedFields: ['category', 'price', 'status']
16
+ })
17
+
18
+ await db.init()
19
+
20
+ try {
21
+ // 1. Insert sample data
22
+ console.log('📝 Inserting sample data...')
23
+ const sampleData = [
24
+ { id: 1, name: 'Apple', category: 'fruits', price: 1.50, status: 'active' },
25
+ { id: 2, name: 'Banana', category: 'fruits', price: 0.80, status: 'active' },
26
+ { id: 3, name: 'Orange', category: 'fruits', price: 1.20, status: 'inactive' },
27
+ { id: 4, name: 'Carrot', category: 'vegetables', price: 0.60, status: 'active' },
28
+ { id: 5, name: 'Broccoli', category: 'vegetables', price: 1.80, status: 'active' },
29
+ { id: 6, name: 'Lettuce', category: 'vegetables', price: 0.90, status: 'inactive' },
30
+ { id: 7, name: 'Milk', category: 'dairy', price: 2.50, status: 'active' },
31
+ { id: 8, name: 'Cheese', category: 'dairy', price: 3.20, status: 'active' },
32
+ { id: 9, name: 'Yogurt', category: 'dairy', price: 1.80, status: 'inactive' },
33
+ { id: 10, name: 'Bread', category: 'bakery', price: 2.00, status: 'active' }
34
+ ]
35
+
36
+ for (const item of sampleData) {
37
+ await db.insert(item)
38
+ }
39
+
40
+ console.log(`✅ Inserted ${sampleData.length} records\n`)
41
+
42
+ // 2. Basic iteration without modifications
43
+ console.log('🔍 Basic iteration - listing all fruits:')
44
+ for await (const entry of db.iterate({ category: 'fruits' })) {
45
+ console.log(` - ${entry.name}: $${entry.price} (${entry.status})`)
46
+ }
47
+ console.log()
48
+
49
+ // 3. Bulk price update with progress tracking
50
+ console.log('💰 Bulk price update - 10% increase for all active items:')
51
+ let processedCount = 0
52
+ let modifiedCount = 0
53
+
54
+ for await (const entry of db.iterate(
55
+ { status: 'active' },
56
+ {
57
+ chunkSize: 5,
58
+ progressCallback: (progress) => {
59
+ if (progress.processed % 5 === 0) {
60
+ console.log(` 📊 Progress: ${progress.processed} processed, ${progress.modified} modified`)
61
+ }
62
+ }
63
+ }
64
+ )) {
65
+ const oldPrice = entry.price
66
+ entry.price = Math.round(entry.price * 1.1 * 100) / 100 // 10% increase, rounded to 2 decimals
67
+ entry.lastUpdated = new Date().toISOString()
68
+
69
+ if (oldPrice !== entry.price) {
70
+ console.log(` 💵 ${entry.name}: $${oldPrice} → $${entry.price}`)
71
+ }
72
+ }
73
+
74
+ console.log(`✅ Price update completed: ${processedCount} processed, ${modifiedCount} modified\n`)
75
+
76
+ // 4. Bulk status change with deletions
77
+ console.log('🗑️ Bulk operations - removing inactive items and updating status:')
78
+ const inactiveItems = await db.find({ status: 'inactive' })
79
+ for (const item of inactiveItems) {
80
+ console.log(` 🗑️ Deleting inactive item: ${item.name}`)
81
+ await db.delete({ id: item.id })
82
+ }
83
+
84
+ // Update remaining items
85
+ for await (const entry of db.iterate({})) {
86
+ if (entry.status === 'active') {
87
+ entry.status = 'available'
88
+ entry.updatedAt = new Date().toISOString()
89
+ }
90
+ }
91
+
92
+ console.log('✅ Bulk operations completed\n')
93
+
94
+ // 5. Verify results
95
+ console.log('📋 Final results:')
96
+ const allItems = await db.find({})
97
+ console.log(`Total items remaining: ${allItems.length}`)
98
+
99
+ for (const item of allItems) {
100
+ console.log(` - ${item.name} (${item.category}): $${item.price} [${item.status}]`)
101
+ }
102
+
103
+ // 6. Performance demonstration with larger dataset
104
+ console.log('\n⚡ Performance test with larger dataset...')
105
+
106
+ // Insert more data for performance test
107
+ const startTime = Date.now()
108
+ for (let i = 11; i <= 1000; i++) {
109
+ await db.insert({
110
+ id: i,
111
+ name: `Product${i}`,
112
+ category: ['electronics', 'clothing', 'books', 'home'][i % 4],
113
+ price: Math.random() * 100,
114
+ status: i % 3 === 0 ? 'inactive' : 'active'
115
+ })
116
+ }
117
+
118
+ const insertTime = Date.now() - startTime
119
+ console.log(`📝 Inserted 990 additional records in ${insertTime}ms`)
120
+
121
+ // Bulk update with performance tracking
122
+ const updateStartTime = Date.now()
123
+ let totalProcessed = 0
124
+
125
+ for await (const entry of db.iterate(
126
+ { status: 'active' },
127
+ {
128
+ chunkSize: 100,
129
+ progressCallback: (progress) => {
130
+ if (progress.completed) {
131
+ totalProcessed = progress.processed
132
+ console.log(`📊 Final stats: ${progress.processed} processed, ${progress.modified} modified in ${progress.elapsed}ms`)
133
+ }
134
+ }
135
+ }
136
+ )) {
137
+ // Add a processing timestamp
138
+ entry.processedAt = Date.now()
139
+ }
140
+
141
+ const updateTime = Date.now() - updateStartTime
142
+ console.log(`⚡ Bulk update completed: ${totalProcessed} records processed in ${updateTime}ms`)
143
+ console.log(`📈 Performance: ${Math.round(totalProcessed / (updateTime / 1000))} records/second`)
144
+
145
+ } finally {
146
+ // Clean up
147
+ await db.close()
148
+ console.log('\n🧹 Database closed and cleaned up')
149
+ }
150
+ }
151
+
152
+ // Run the demonstration
153
+ if (import.meta.url === `file://${process.argv[1]}`) {
154
+ demonstrateIterate().catch(console.error)
155
+ }
156
+
157
+ export { demonstrateIterate }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Simple example of the iterate() method
3
+ * Demonstrates bulk updates with streaming performance
4
+ */
5
+
6
+ import { Database } from '../src/Database.mjs'
7
+
8
+ async function simpleIterateExample() {
9
+ console.log('🚀 JexiDB iterate() Method - Simple Example\n')
10
+
11
+ // Create database
12
+ const db = new Database('simple-iterate.jdb', {
13
+ debugMode: false,
14
+ termMapping: true,
15
+ indexedFields: ['category', 'price']
16
+ })
17
+
18
+ await db.init()
19
+
20
+ try {
21
+ // 1. Insert sample data
22
+ console.log('📝 Inserting sample data...')
23
+ const products = [
24
+ { id: 1, name: 'Apple', category: 'fruits', price: 1.50, inStock: true },
25
+ { id: 2, name: 'Banana', category: 'fruits', price: 0.80, inStock: true },
26
+ { id: 3, name: 'Orange', category: 'fruits', price: 1.20, inStock: false },
27
+ { id: 4, name: 'Carrot', category: 'vegetables', price: 0.60, inStock: true },
28
+ { id: 5, name: 'Broccoli', category: 'vegetables', price: 1.80, inStock: true }
29
+ ]
30
+
31
+ for (const product of products) {
32
+ await db.insert(product)
33
+ }
34
+
35
+ console.log(`✅ Inserted ${products.length} products\n`)
36
+
37
+ // 2. Basic iteration - list all fruits
38
+ console.log('🍎 Listing all fruits:')
39
+ for await (const entry of db.iterate({ category: 'fruits' })) {
40
+ console.log(` - ${entry.name}: $${entry.price} (${entry.inStock ? 'in stock' : 'out of stock'})`)
41
+ }
42
+ console.log()
43
+
44
+ // 3. Bulk price update - 10% increase for in-stock items
45
+ console.log('💰 Bulk price update - 10% increase for in-stock items:')
46
+ let updatedCount = 0
47
+
48
+ for await (const entry of db.iterate({ inStock: true })) {
49
+ const oldPrice = entry.price
50
+ entry.price = Math.round(entry.price * 1.1 * 100) / 100 // 10% increase
51
+ entry.lastUpdated = new Date().toISOString()
52
+
53
+ if (oldPrice !== entry.price) {
54
+ console.log(` 💵 ${entry.name}: $${oldPrice} → $${entry.price}`)
55
+ updatedCount++
56
+ }
57
+ }
58
+
59
+ console.log(`✅ Updated ${updatedCount} products\n`)
60
+
61
+ // 4. Bulk status update - mark all vegetables as organic
62
+ console.log('🌱 Marking all vegetables as organic:')
63
+ let organicCount = 0
64
+
65
+ for await (const entry of db.iterate({ category: 'vegetables' })) {
66
+ entry.organic = true
67
+ entry.certifiedAt = new Date().toISOString()
68
+ console.log(` 🌱 ${entry.name} is now organic`)
69
+ organicCount++
70
+ }
71
+
72
+ console.log(`✅ Marked ${organicCount} vegetables as organic\n`)
73
+
74
+ // 5. Performance test with progress tracking
75
+ console.log('⚡ Performance test with progress tracking:')
76
+ let processedCount = 0
77
+
78
+ for await (const entry of db.iterate(
79
+ {}, // All records
80
+ {
81
+ chunkSize: 2,
82
+ progressCallback: (progress) => {
83
+ if (progress.completed) {
84
+ console.log(`📊 Final stats: ${progress.processed} processed, ${progress.modified} modified in ${progress.elapsed}ms`)
85
+ }
86
+ }
87
+ }
88
+ )) {
89
+ // Add processing timestamp
90
+ entry.processedAt = Date.now()
91
+ processedCount++
92
+ }
93
+
94
+ console.log(`⚡ Processed ${processedCount} records\n`)
95
+
96
+ // 6. Verify all changes
97
+ console.log('📋 Final results:')
98
+ const allProducts = await db.find({})
99
+ for (const product of allProducts) {
100
+ console.log(` - ${product.name} (${product.category}): $${product.price} ${product.organic ? '🌱' : ''} ${product.inStock ? '✅' : '❌'}`)
101
+ }
102
+
103
+ } finally {
104
+ // Clean up
105
+ await db.close()
106
+ console.log('\n🧹 Database closed and cleaned up')
107
+ }
108
+ }
109
+
110
+ // Run the example
111
+ if (import.meta.url === `file://${process.argv[1]}`) {
112
+ simpleIterateExample().catch(console.error)
113
+ }
114
+
115
+ export { simpleIterateExample }
package/jest.config.js ADDED
@@ -0,0 +1,24 @@
1
+ export default {
2
+ testEnvironment: 'node',
3
+ testMatch: ['**/test/**/*.test.js', '**/test/**/*.test.mjs'],
4
+ collectCoverage: true,
5
+ coverageDirectory: 'coverage',
6
+ coverageReporters: ['text', 'lcov', 'html'],
7
+ coveragePathIgnorePatterns: [
8
+ '/node_modules/',
9
+ '/test/',
10
+ '/dist/'
11
+ ],
12
+ verbose: true,
13
+ testTimeout: 10000,
14
+ maxWorkers: '50%', // Allow parallel test execution for better performance
15
+ detectOpenHandles: true, // Detect open handles to identify resource leaks
16
+ transform: {
17
+ '^.+\\.mjs$': 'babel-jest',
18
+ '^.+\\.js$': 'babel-jest'
19
+ },
20
+ transformIgnorePatterns: [
21
+ 'node_modules/(?!(.*\\.mjs$|p-limit|yocto-queue))'
22
+ ],
23
+ setupFilesAfterEnv: ['<rootDir>/test/setup.js']
24
+ };
package/package.json CHANGED
@@ -1,65 +1,77 @@
1
1
  {
2
2
  "name": "jexidb",
3
- "version": "2.0.2",
4
- "description": "JexiDB - A fast and reliable local CRUD database for Electron apps with pure JavaScript JSONL architecture",
5
- "main": "./dist/index.js",
6
- "module": "./src/index.js",
7
- "types": "./dist/index.d.ts",
3
+ "version": "2.1.0",
4
+ "type": "module",
5
+ "description": "JexiDB is a pure JS NPM library for managing data on disk efficiently, without the need for a server.",
6
+ "main": "./dist/Database.cjs",
7
+ "module": "./src/Database.mjs",
8
8
  "exports": {
9
9
  ".": {
10
- "import": "./src/index.js",
11
- "require": "./dist/index.js",
12
- "types": "./dist/index.d.ts"
13
- },
14
- "./package.json": "./package.json"
10
+ "require": "./dist/Database.cjs",
11
+ "import": "./src/Database.mjs"
12
+ }
15
13
  },
16
14
  "scripts": {
17
- "build": "babel src -d dist",
18
- "dev": "babel src -d dist --watch",
19
- "test": "jest && node scripts/cleanup-after-tests.js",
15
+ "test": "node scripts/run-tests.js",
20
16
  "test:watch": "jest --watch",
21
- "test:clean": "node scripts/cleanup-after-tests.js",
22
- "test:optimized": "node scripts/optimize-tests.js --performance",
23
- "test:parallel": "node scripts/optimize-tests.js --parallel --workers 4",
24
- "test:fast": "node scripts/optimize-tests.js --parallel --workers 4 --performance --no-isolation",
25
- "prepublishOnly": "npm run build",
26
- "generate-test-db": "node scripts/run-test-db.js",
27
- "generate-test-db:multiple": "node scripts/run-test-db.js --multiple",
28
- "list-test-dbs": "node scripts/list-test-dbs.js",
29
- "verify-test-db": "node scripts/verify-test-db.js",
30
- "test-optimization": "node scripts/test-optimization.js",
31
- "benchmark-compression": "node scripts/benchmark-compression.js",
32
- "benchmark-performance": "node scripts/benchmark-performance.js",
33
- "generate-docs": "node scripts/generate-docs.js"
17
+ "test:coverage": "jest --coverage && npm run clean:test-files",
18
+ "test:legacy": "node --expose-gc test/test.mjs",
19
+ "clean:test-files": "node scripts/clean-test-files.js",
20
+ "build": "npx babel src/Database.mjs --plugins @babel/plugin-transform-async-generator-functions --out-file-extension .cjs --out-dir dist",
21
+ "prepare": "node scripts/prepare.js"
34
22
  },
35
- "keywords": [
36
- "database",
37
- "crud",
38
- "local",
39
- "electron",
40
- "javascript",
41
- "json",
42
- "storage",
43
- "jexidb",
44
- "jsonl",
45
- "nosql"
46
- ],
47
- "author": "Edenware",
23
+ "author": "EdenwareApps",
48
24
  "license": "MIT",
49
25
  "devDependencies": {
50
- "@babel/cli": "^7.23.0",
51
- "@babel/core": "^7.23.0",
52
- "@babel/preset-env": "^7.23.0",
53
- "jest": "^29.7.0"
26
+ "@babel/cli": "^7.25.6",
27
+ "@babel/core": "^7.25.2",
28
+ "@babel/plugin-transform-async-generator-functions": "^7.25.4",
29
+ "@babel/preset-env": "^7.28.3",
30
+ "@rollup/plugin-commonjs": "^28.0.6",
31
+ "@rollup/plugin-node-resolve": "^16.0.1",
32
+ "babel-jest": "^30.0.5",
33
+ "jest": "^30.1.3",
34
+ "jest-extended": "^6.0.0",
35
+ "rollup": "^4.48.1"
36
+ },
37
+ "dependencies": {
38
+ "@valentech/sializer": "^0.3.9",
39
+ "async-mutex": "^0.5.0",
40
+ "p-limit": "^6.1.0"
41
+ },
42
+ "optionalDependencies": {
43
+ "fast-deep-equal": "^3.1.3",
44
+ "fast-json-stringify": "^5.7.0",
45
+ "msgpack": "^1.0.3"
54
46
  },
55
- "engines": {
56
- "node": ">=14.0.0"
47
+ "directories": {
48
+ "test": "test"
57
49
  },
58
- "files": [
59
- "dist",
60
- "src",
61
- "README.md"
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/EdenwareApps/jexidb.git"
53
+ },
54
+ "keywords": [
55
+ "couchdb",
56
+ "database",
57
+ "nosql",
58
+ "pouchdb",
59
+ "local-storage",
60
+ "db",
61
+ "persistent-storage",
62
+ "dexiejs",
63
+ "embedded-database",
64
+ "data-management",
65
+ "nedb",
66
+ "lowdb",
67
+ "dexie",
68
+ "offline-database",
69
+ "simple-database",
70
+ "fast-database",
71
+ "jexidb"
62
72
  ],
63
- "dependencies": {
64
- }
73
+ "bugs": {
74
+ "url": "https://github.com/EdenwareApps/jexidb/issues"
75
+ },
76
+ "homepage": "https://github.com/EdenwareApps/jexidb#readme"
65
77
  }
@@ -0,0 +1,47 @@
1
+ # Scripts
2
+
3
+ This directory contains utility scripts for the JexiDB project.
4
+
5
+ ## clean-test-files.js
6
+
7
+ A Node.js script that automatically cleans up test files generated during test execution.
8
+
9
+ ### Usage
10
+
11
+ ```bash
12
+ # Run manually
13
+ node scripts/clean-test-files.js
14
+
15
+ # Run via npm script
16
+ npm run clean:test-files
17
+ ```
18
+
19
+ ### What it cleans
20
+
21
+ The script removes files matching these patterns:
22
+ - `test-db-*` (with or without extensions)
23
+ - `test-db-*.jdb`
24
+ - `test-db-*.idx.jdb` (contains both index and offsets data)
25
+ - `test-normalize*` (with or without extensions)
26
+ - `test-confusion*` (with or without extensions)
27
+ - `debug-*` (with or without extensions)
28
+ - `test-simple-*`
29
+ - `test-count.jdb`
30
+
31
+ ### Integration with npm test
32
+
33
+ The cleanup script is automatically executed after running tests:
34
+
35
+ ```bash
36
+ npm test # Runs jest && npm run clean:test-files
37
+ ```
38
+
39
+ This ensures that test files are automatically cleaned up after each test run, keeping the project directory clean.
40
+
41
+ ### Features
42
+
43
+ - **Pattern-based cleanup**: Uses regex patterns to identify test files
44
+ - **Safe deletion**: Only deletes files, not directories
45
+ - **Error handling**: Continues execution even if some files can't be deleted
46
+ - **Verbose output**: Shows which files were cleaned
47
+ - **Summary**: Reports total number of files cleaned