jexidb 2.0.3 → 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 (67) hide show
  1. package/.babelrc +13 -0
  2. package/.gitattributes +2 -0
  3. package/CHANGELOG.md +132 -101
  4. package/LICENSE +21 -21
  5. package/README.md +301 -639
  6. package/babel.config.json +5 -0
  7. package/dist/Database.cjs +3896 -0
  8. package/docs/API.md +1051 -390
  9. package/docs/EXAMPLES.md +701 -177
  10. package/docs/README.md +194 -184
  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 -54
  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 -1333
  50. package/dist/index.js +0 -617
  51. package/docs/MIGRATION.md +0 -295
  52. package/examples/auto-save-example.js +0 -158
  53. package/examples/cjs-usage.cjs +0 -82
  54. package/examples/close-vs-delete-example.js +0 -71
  55. package/examples/esm-usage.js +0 -113
  56. package/examples/example-columns.idx.jdb +0 -0
  57. package/examples/example-columns.jdb +0 -9
  58. package/examples/example-options.idx.jdb +0 -0
  59. package/examples/example-options.jdb +0 -0
  60. package/examples/example-users.idx.jdb +0 -0
  61. package/examples/example-users.jdb +0 -5
  62. package/examples/simple-test.js +0 -55
  63. package/src/FileHandler.js +0 -674
  64. package/src/IndexManager.js +0 -363
  65. package/src/IntegrityChecker.js +0 -379
  66. package/src/JSONLDatabase.js +0 -1391
  67. package/src/index.js +0 -608
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,68 +1,77 @@
1
1
  {
2
2
  "name": "jexidb",
3
- "version": "2.0.3",
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",
62
- "CHANGELOG.md",
63
- "docs",
64
- "examples"
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"
65
72
  ],
66
- "dependencies": {
67
- }
73
+ "bugs": {
74
+ "url": "https://github.com/EdenwareApps/jexidb/issues"
75
+ },
76
+ "homepage": "https://github.com/EdenwareApps/jexidb#readme"
68
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
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+
6
+ function cleanTestFiles() {
7
+ const startTime = Date.now();
8
+ const currentDir = process.cwd();
9
+ const files = fs.readdirSync(currentDir);
10
+
11
+ const testFilePatterns = [
12
+ /^test-db-.*\.jdb$/,
13
+ /^test-db-.*\.offsets\.jdb$/,
14
+ /^test-db-.*\.idx\.jdb$/,
15
+ /^test-db-.*$/, // Files without extension
16
+ /^test-normalize.*\.jdb$/,
17
+ /^test-normalize.*\.offsets\.jdb$/,
18
+ /^test-normalize.*\.idx\.jdb$/,
19
+ /^test-normalize.*$/, // Files without extension
20
+ /^test-confusion.*\.jdb$/,
21
+ /^test-confusion.*\.offsets\.jdb$/,
22
+ /^test-confusion.*\.idx\.jdb$/,
23
+ /^test-confusion.*$/, // Files without extension
24
+ /^debug-.*\.jdb$/,
25
+ /^debug-.*\.offsets\.jdb$/,
26
+ /^debug-.*\.idx\.jdb$/,
27
+ /^debug-.*$/, // Files without extension
28
+ /^test-simple-.*$/, // test-simple files
29
+ /^test-count\.jdb$/, // test-count.jdb file
30
+ /^test-index-persistence-.*\.jdb$/, // index persistence test files
31
+ /^test-index-persistence-.*\.idx\.jdb$/, // index persistence idx files
32
+ /^test-indexed-mode-.*\.jdb$/, // indexed mode test files
33
+ /^test-indexed-mode-.*\.idx\.jdb$/, // indexed mode idx files
34
+ /^test-term-mapping-.*\.jdb$/, // term mapping test files
35
+ /^test-term-mapping-.*\.idx\.jdb$/, // term mapping idx files
36
+ /^test-.*\.jdb$/, // Any test file with .jdb extension
37
+ /^test-.*\.idx\.jdb$/ // Any test file with .idx.jdb extension
38
+ ];
39
+
40
+ let cleanedCount = 0;
41
+
42
+ files.forEach(file => {
43
+ const filePath = path.join(currentDir, file);
44
+ const stats = fs.statSync(filePath);
45
+
46
+ if (stats.isFile()) {
47
+ const shouldDelete = testFilePatterns.some(pattern => pattern.test(file));
48
+
49
+ if (shouldDelete) {
50
+ try {
51
+ fs.unlinkSync(filePath);
52
+ cleanedCount++;
53
+ } catch (error) {
54
+ console.warn(`Warning: Could not delete ${file}: ${error.message}`);
55
+ }
56
+ }
57
+ }
58
+ });
59
+
60
+ const endTime = Date.now();
61
+ const duration = endTime - startTime;
62
+
63
+ if (cleanedCount > 0) {
64
+ console.log(`✅ Cleaned ${cleanedCount} test files.`);
65
+ } else {
66
+ console.log('No test files found to clean.');
67
+ }
68
+ }
69
+
70
+ // Run cleanup if this script is executed directly
71
+ if (import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith('clean-test-files.js')) {
72
+ cleanTestFiles();
73
+ }
74
+
75
+ export default cleanTestFiles;
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { existsSync } from 'fs';
4
+ import { execSync } from 'child_process';
5
+ import { fileURLToPath } from 'url';
6
+ import { dirname, join } from 'path';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+ const rootDir = join(__dirname, '..');
11
+ const distFile = join(rootDir, 'dist', 'Database.cjs');
12
+
13
+ // Check if the bundle already exists
14
+ if (existsSync(distFile)) {
15
+ console.log('✅ Bundle already exists, skipping build');
16
+ process.exit(0);
17
+ }
18
+
19
+ console.log('📦 Bundle not found, building...');
20
+
21
+ try {
22
+ execSync('npm run build', {
23
+ stdio: 'inherit',
24
+ cwd: rootDir
25
+ });
26
+ console.log('✅ Build completed successfully');
27
+ } catch (error) {
28
+ console.error('❌ Build failed:', error.message);
29
+ process.exit(1);
30
+ }
31
+
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn } from 'child_process'
4
+ import { fileURLToPath } from 'url'
5
+ import { dirname, join } from 'path'
6
+
7
+ const __filename = fileURLToPath(import.meta.url)
8
+ const __dirname = dirname(__filename)
9
+
10
+ async function runTests() {
11
+ const startTime = Date.now()
12
+
13
+ console.log('🧪 Running JexiDB tests...')
14
+
15
+ // Run Jest tests
16
+ const jestProcess = spawn('npx', ['jest', ...process.argv.slice(2)], {
17
+ stdio: 'inherit',
18
+ shell: true
19
+ })
20
+
21
+ jestProcess.on('close', async (code) => {
22
+ if (code !== 0) {
23
+ console.error(`❌ Tests failed with exit code ${code}`)
24
+ process.exit(code)
25
+ }
26
+
27
+ // Run cleanup
28
+ const cleanupProcess = spawn('npm', ['run', 'clean:test-files'], {
29
+ stdio: 'inherit',
30
+ shell: true
31
+ })
32
+
33
+ cleanupProcess.on('close', (cleanupCode) => {
34
+ const endTime = Date.now()
35
+ const duration = Math.round((endTime - startTime) / 1000)
36
+
37
+ // Display completion time
38
+ const completionTime = new Date().toLocaleString('en-US', {
39
+ year: 'numeric',
40
+ month: '2-digit',
41
+ day: '2-digit',
42
+ hour: '2-digit',
43
+ minute: '2-digit',
44
+ second: '2-digit',
45
+ hour12: true
46
+ });
47
+
48
+ console.log(`✅ Tests completed at: ${completionTime}`);
49
+ console.log(`📦 Total execution time: ${duration}s`)
50
+
51
+ if (cleanupCode !== 0) {
52
+ console.warn(`⚠️ Cleanup completed with warnings (exit code: ${cleanupCode})`)
53
+ }
54
+
55
+ process.exit(0)
56
+ })
57
+ })
58
+
59
+ jestProcess.on('error', (error) => {
60
+ console.error('❌ Failed to start Jest:', error.message)
61
+ process.exit(1)
62
+ })
63
+ }
64
+
65
+ // Handle process termination
66
+ process.on('SIGINT', () => {
67
+ console.log('\n🛑 Test execution interrupted by user')
68
+ process.exit(0)
69
+ })
70
+
71
+ process.on('SIGTERM', () => {
72
+ console.log('\n🛑 Test execution terminated')
73
+ process.exit(0)
74
+ })
75
+
76
+ // Run the tests
77
+ runTests().catch(error => {
78
+ console.error('❌ Fatal error:', error.message)
79
+ process.exit(1)
80
+ })