nodejs-json-db 0.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Rashed Iqbal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,348 @@
1
+ # nodejs-json-db
2
+
3
+ [![npm version](https://img.shields.io/npm/v/nodejs-json-db.svg)](https://www.npmjs.com/package/nodejs-json-db)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
6
+
7
+ A production-ready, lightweight JSON-based database for Node.js and Electron applications. Zero external database dependencies, fully typed, with a MongoDB-like query API and optional high-concurrency mode.
8
+
9
+ ## โœจ Features
10
+
11
+ - ๐Ÿš€ **Zero Dependencies** - No external database server required
12
+ - ๐Ÿ“ฆ **Dual Module Support** - Works with both ESM and CommonJS
13
+ - ๐Ÿ”’ **Type-Safe** - Full TypeScript support with generics
14
+ - ๐Ÿ” **MongoDB-like Queries** - Familiar query operators (`$eq`, `$gt`, `$in`, `$regex`, etc.)
15
+ - โšก **High Performance** - Memory caching with atomic file writes
16
+ - ๐Ÿ”„ **High-Concurrency Mode** - Partitioned storage with write batching for massive throughput
17
+ - โœ… **Schema Validation** - Optional Zod integration for document validation
18
+ - ๐Ÿ–ฅ๏ธ **Electron Ready** - Perfect for desktop applications
19
+ - ๐Ÿงช **Well Tested** - 107 tests with comprehensive coverage
20
+
21
+ ## ๐Ÿ“ฆ Installation
22
+
23
+ ```bash
24
+ npm install nodejs-json-db
25
+ ```
26
+
27
+ ```bash
28
+ yarn add nodejs-json-db
29
+ ```
30
+
31
+ For schema validation (optional):
32
+ ```bash
33
+ npm install zod
34
+ ```
35
+
36
+ ## ๐Ÿš€ Quick Start
37
+
38
+ ```typescript
39
+ import { JsonDB, Document } from 'nodejs-json-db';
40
+
41
+ interface User extends Document {
42
+ _id: string;
43
+ name: string;
44
+ email: string;
45
+ age: number;
46
+ }
47
+
48
+ const db = new JsonDB({ dataDir: './data' });
49
+ await db.connect();
50
+
51
+ const users = db.collection<User>('users');
52
+
53
+ // Insert
54
+ const user = await users.insert({
55
+ name: 'John Doe',
56
+ email: 'john@example.com',
57
+ age: 30,
58
+ });
59
+
60
+ // Find
61
+ const found = await users.findOne({ email: 'john@example.com' });
62
+
63
+ // Update
64
+ await users.updateById(user._id, { $set: { age: 31 } });
65
+
66
+ // Delete
67
+ await users.deleteById(user._id);
68
+
69
+ await db.close();
70
+ ```
71
+
72
+ ## ๐Ÿ“Š Benchmarks
73
+
74
+ Performance tested with documents up to 1 million records:
75
+
76
+ ### Write Performance (insertMany)
77
+
78
+ | Documents | Standard Mode | High-Concurrency Mode |
79
+ |-----------|---------------|----------------------|
80
+ | 100,000 | 390K docs/sec (56 MB/s) | 355K docs/sec (51 MB/s) |
81
+ | 500,000 | 382K docs/sec (55 MB/s) | **423K docs/sec (61 MB/s)** โœ… |
82
+ | 1,000,000 | 392K docs/sec (56 MB/s) | **392K docs/sec (56 MB/s)** |
83
+
84
+ ### Read Performance (find)
85
+
86
+ | Documents | Standard Mode | High-Concurrency Mode |
87
+ |-----------|---------------|----------------------|
88
+ | 1,000 | 648K docs/sec (93 MB/s) | **803K docs/sec (115 MB/s)** โœ… |
89
+ | 10,000 | 1.5M docs/sec (218 MB/s) | **2.2M docs/sec (309 MB/s)** โœ… |
90
+ | 100,000+ | **2.8M+ docs/sec** | 2.0M docs/sec |
91
+
92
+ Run benchmarks yourself:
93
+ ```bash
94
+ npx tsx examples/benchmark.ts
95
+ ```
96
+
97
+ ## ๐Ÿ”„ High-Concurrency Mode
98
+
99
+ For applications handling thousands of concurrent requests, enable high-concurrency mode:
100
+
101
+ ```typescript
102
+ const db = new JsonDB({
103
+ dataDir: './data',
104
+ highConcurrency: {
105
+ enabled: true,
106
+ partitions: 16, // Data shards (default: 16)
107
+ batchSize: 1000, // Writes before auto-flush (default: 1000)
108
+ flushInterval: 100, // Max ms before flush (default: 100)
109
+ maxConcurrentIO: 4, // Parallel I/O operations (default: 4)
110
+ },
111
+ });
112
+
113
+ await db.connect();
114
+ const users = db.collection('users');
115
+
116
+ // Fast parallel inserts (skips duplicate check)
117
+ await Promise.all(
118
+ Array.from({ length: 10000 }, (_, i) =>
119
+ users.insertFast({ name: `User ${i}`, email: `user${i}@test.com` })
120
+ )
121
+ );
122
+
123
+ // Always flush before shutdown
124
+ await db.flush();
125
+ await db.close();
126
+ ```
127
+
128
+ ### When to Use High-Concurrency Mode
129
+
130
+ | Use Case | Recommended Mode |
131
+ |----------|-----------------|
132
+ | Desktop apps, small datasets | Standard |
133
+ | Web servers with concurrent requests | High-Concurrency |
134
+ | Bulk data import | Either (both fast) |
135
+ | Real-time applications | High-Concurrency |
136
+
137
+ ## โœ… Schema Validation (Zod)
138
+
139
+ Validate documents before insertion using Zod schemas:
140
+
141
+ ```typescript
142
+ import { z } from 'zod';
143
+ import { JsonDB, ValidationError } from 'nodejs-json-db';
144
+
145
+ const UserSchema = z.object({
146
+ _id: z.string(),
147
+ name: z.string().min(1),
148
+ email: z.string().email(),
149
+ age: z.number().int().positive().optional(),
150
+ });
151
+
152
+ type User = z.infer<typeof UserSchema>;
153
+
154
+ const db = new JsonDB({ dataDir: './data' });
155
+ await db.connect();
156
+
157
+ // Pass schema when creating collection
158
+ const users = db.collection<User>('users', { schema: UserSchema });
159
+
160
+ // โœ… Valid - inserts successfully
161
+ await users.insert({ name: 'John', email: 'john@example.com' });
162
+
163
+ // โŒ Invalid - throws ValidationError
164
+ try {
165
+ await users.insert({ name: '', email: 'not-an-email' });
166
+ } catch (error) {
167
+ if (error instanceof ValidationError) {
168
+ console.log(error.issues); // [{path: ['name'], message: '...'}, ...]
169
+ }
170
+ }
171
+ ```
172
+
173
+ ## ๐Ÿ“– API Reference
174
+
175
+ ### JsonDB Options
176
+
177
+ | Option | Type | Default | Description |
178
+ |--------|------|---------|-------------|
179
+ | `dataDir` | `string` | **required** | Path to store JSON files |
180
+ | `autoSave` | `boolean` | `true` | Auto-save after writes |
181
+ | `saveDebounce` | `number` | `0` | Debounce time (ms) for saves |
182
+ | `prettyPrint` | `boolean` | `true` | Format JSON files |
183
+ | `fileExtension` | `string` | `.json` | Custom file extension |
184
+ | `highConcurrency` | `object` | `undefined` | Enable high-concurrency mode |
185
+
186
+ ### JsonDB Methods
187
+
188
+ ```typescript
189
+ await db.connect(); // Initialize database
190
+ await db.close(); // Close connection
191
+ db.collection<T>('name', {schema?}); // Get typed collection
192
+ await db.listCollections(); // List all collections
193
+ await db.hasCollection('name'); // Check if exists
194
+ await db.dropCollection('name'); // Delete collection
195
+ await db.drop(); // Delete all collections
196
+ await db.flush(); // Flush pending writes
197
+ db.isHighConcurrencyMode(); // Check mode
198
+ db.getStats(); // Get HC stats (if enabled)
199
+ ```
200
+
201
+ ### Collection Methods
202
+
203
+ ```typescript
204
+ // Insert
205
+ await collection.insert(doc); // With duplicate check
206
+ await collection.insertFast(doc); // Skip duplicate check (faster)
207
+ await collection.insertMany(docs); // Bulk insert
208
+
209
+ // Find
210
+ await collection.find(query?, options?); // Find matching docs
211
+ await collection.findOne(query); // Find first match
212
+ await collection.findById(id); // Find by ID
213
+ await collection.count(query?); // Count matches
214
+ await collection.getAll(); // Get all documents
215
+
216
+ // Update
217
+ await collection.update(query, update); // Update many
218
+ await collection.updateOne(query, update); // Update first match
219
+ await collection.updateById(id, update); // Update by ID
220
+
221
+ // Delete
222
+ await collection.delete(query); // Delete many
223
+ await collection.deleteOne(query); // Delete first match
224
+ await collection.deleteById(id); // Delete by ID
225
+ await collection.clear(); // Clear all documents
226
+ await collection.drop(); // Drop collection
227
+
228
+ // Utility
229
+ await collection.flush(); // Force save pending writes
230
+ collection.getName(); // Get collection name
231
+ ```
232
+
233
+ ## ๐Ÿ” Query Operators
234
+
235
+ ### Comparison
236
+
237
+ | Operator | Example |
238
+ |----------|---------|
239
+ | `$eq` | `{ age: { $eq: 25 } }` |
240
+ | `$ne` | `{ status: { $ne: 'deleted' } }` |
241
+ | `$gt` / `$gte` | `{ age: { $gte: 18 } }` |
242
+ | `$lt` / `$lte` | `{ price: { $lt: 100 } }` |
243
+ | `$in` / `$nin` | `{ role: { $in: ['admin', 'mod'] } }` |
244
+
245
+ ### String
246
+
247
+ | Operator | Example |
248
+ |----------|---------|
249
+ | `$regex` | `{ email: { $regex: /@gmail\.com$/ } }` |
250
+ | `$startsWith` | `{ name: { $startsWith: 'John' } }` |
251
+ | `$endsWith` | `{ email: { $endsWith: '.com' } }` |
252
+
253
+ ### Logical
254
+
255
+ ```typescript
256
+ // AND (implicit)
257
+ { active: true, age: { $gte: 18 } }
258
+
259
+ // OR
260
+ { $or: [{ role: 'admin' }, { role: 'mod' }] }
261
+
262
+ // NOT
263
+ { $not: { status: 'deleted' } }
264
+ ```
265
+
266
+ ### Existence
267
+
268
+ ```typescript
269
+ { email: { $exists: true } } // Field exists
270
+ { deletedAt: { $exists: false } } // Field doesn't exist
271
+ ```
272
+
273
+ ## ๐Ÿ“ Update Operators
274
+
275
+ | Operator | Description | Example |
276
+ |----------|-------------|---------|
277
+ | `$set` | Set field | `{ $set: { name: 'New' } }` |
278
+ | `$unset` | Remove field | `{ $unset: { temp: true } }` |
279
+ | `$inc` | Increment | `{ $inc: { views: 1 } }` |
280
+ | `$push` | Add to array | `{ $push: { tags: 'new' } }` |
281
+ | `$pull` | Remove from array | `{ $pull: { tags: 'old' } }` |
282
+ | `$addToSet` | Add unique | `{ $addToSet: { tags: 'unique' } }` |
283
+
284
+ ## ๐Ÿ–ฅ๏ธ Electron Integration
285
+
286
+ ```typescript
287
+ import { app } from 'electron';
288
+ import { JsonDB } from 'nodejs-json-db';
289
+ import path from 'path';
290
+
291
+ const db = new JsonDB({
292
+ dataDir: path.join(app.getPath('userData'), 'database'),
293
+ });
294
+
295
+ await db.connect();
296
+ ```
297
+
298
+ ## ๐Ÿ“ Data Storage
299
+
300
+ Standard mode stores one JSON file per collection:
301
+ ```
302
+ data/
303
+ โ”œโ”€โ”€ users.json
304
+ โ”œโ”€โ”€ posts.json
305
+ โ””โ”€โ”€ settings.json
306
+ ```
307
+
308
+ High-concurrency mode partitions data:
309
+ ```
310
+ data/
311
+ โ”œโ”€โ”€ users_p0.json
312
+ โ”œโ”€โ”€ users_p1.json
313
+ โ”œโ”€โ”€ users_p2.json
314
+ โ””โ”€โ”€ ...
315
+ ```
316
+
317
+ ## ๐Ÿงช Examples
318
+
319
+ ```bash
320
+ # Basic usage
321
+ npx tsx examples/basic-usage.ts
322
+
323
+ # Schema validation
324
+ npx tsx examples/schema-example.ts
325
+
326
+ # Benchmark
327
+ npx tsx examples/benchmark.ts
328
+ ```
329
+
330
+ ## ๐Ÿ”ง Development
331
+
332
+ ```bash
333
+ # Install dependencies
334
+ yarn install
335
+
336
+ # Run tests
337
+ yarn test
338
+
339
+ # Build
340
+ yarn build
341
+
342
+ # Lint
343
+ yarn lint
344
+ ```
345
+
346
+ ## ๐Ÿ“„ License
347
+
348
+ MIT ยฉ [Rashed Iqbal](https://github.com/iqbal-rashed)