Jsoning
Jsoning is a lightweight, key-value JSON-based persistent database library designed for Node.js environments. It currently maintains version 1.0.1 and has a moderate release cadence, with significant updates like the v1.0.0 TypeScript rewrite. The library focuses on ease of use and beginner-friendliness, providing a simple API for common database operations such as setting, getting, pushing, and deleting data within JSON files. Key differentiators include atomic file writing to prevent data corruption, built-in TypeScript support, and EventEmitter integration for reacting to database changes, making it suitable for small projects, prototyping, and educational purposes. It requires Node.js v16 or greater for operation.
Common errors
-
TypeError: Jsoning is not a constructor
cause Attempting to import `Jsoning` using CommonJS `require()` syntax or as a default import when it's an ESM named export (since v1.0.0).fixChange your import statement to `import { Jsoning } from 'jsoning';` and ensure your environment supports ES modules (Node.js >=16 with `type: 'module'` in `package.json`). -
(node:XXXX) UnhandledPromiseRejectionWarning: TypeError: (intermediate value).then is not a function
cause An asynchronous `jsoning` method (like `set`, `get`, `all`) was called without `await`, and its returned Promise was not handled.fixEnsure all calls to `jsoning` methods are `await`ed within an `async` function. For example, `await db.set('key', 'value');`. -
Error: ENOENT: no such file or directory, open 'database.json'
cause The specified database file path is incorrect, or the `jsoning` instance is trying to access/create the file in an unexpected location due to changes in current working directory handling (since v0.10.19).fixProvide an absolute path to the `Jsoning` constructor (e.g., `new Jsoning(path.join(__dirname, 'data', 'my-db.json'))`) to ensure the file is always accessed from a predictable location. -
ReferenceError: MathOps is not defined
cause Attempting to use the `MathOps` enum without explicitly importing it as a named export.fixAdd `import { MathOps } from 'jsoning';` to your file alongside the `Jsoning` import.
Warnings
- breaking Since v1.0.0, jsoning has been rewritten in TypeScript and moved to an ESM-first architecture. This requires `import` syntax and Node.js v16 or higher. Older CommonJS `require()` statements will not work for importing `Jsoning`.
- breaking Prior to v0.13.23, the `get()` method would return `false` if a key was not found. Since v0.13.23, it correctly returns `null` for non-existent keys. Applications relying on the `false` return value for logic might need adjustment.
- gotcha From v0.10.19, JSON database files are generated and chosen relative to the current working directory where the Node.js process is executed. This can cause issues if your application's CWD changes or if you expect files in a fixed location relative to your script.
- breaking A prototype pollution vulnerability was discovered and patched in v0.9.18. Users running versions prior to 0.9.18 are strongly advised to update immediately to mitigate potential security risks.
- gotcha Many `jsoning` methods (e.g., `set`, `get`, `push`, `delete`, `all`) are asynchronous and return Promises. Forgetting to use `await` or handle these Promises can lead to unhandled promise rejections, incorrect data, or unexpected program flow.
Install
-
npm install jsoning -
yarn add jsoning -
pnpm add jsoning
Imports
- Jsoning
const Jsoning = require('jsoning');import { Jsoning } from 'jsoning'; - MathOps
const MathOps = require('jsoning').MathOps;import { MathOps } from 'jsoning'; - Jsoning (Type)
import { Jsoning } from 'jsoning';import type { Jsoning } from 'jsoning';
Quickstart
import { Jsoning, MathOps } from 'jsoning';
import { createRequire } from 'module';
import path from 'path';
import { fileURLToPath } from 'url';
const require = createRequire(import.meta.url);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const dbPath = path.join(__dirname, 'temp-database.json');
const db = new Jsoning(dbPath);
async function runExample() {
console.log('--- Initializing Database ---');
await db.clear(); // Ensure a clean start
// Set some values with a key
await db.set('birthday', '07-aug');
await db.set('age', '13');
console.log('Set birthday and age.');
// Push stuff to an array for a particular key
await db.push('transformers', 'optimus prime');
await db.push('transformers', 'bumblebee');
await db.push('transformers', 'iron hide');
console.log('Pushed transformers.');
// Get the value of a key
console.log('Transformers:', await db.get('transformers'));
// Get all the values
console.log('All data:', await db.all());
// does such a value exist?
console.log('Has "value2"?', await db.has('value2'));
// My age keeps changing, so I'm deleting it
console.log('Deleted age:', await db.delete('age'));
// I got $100 for my birthday
await db.set('money', 100);
// and someone gave me $200 more
await db.math('money', MathOps.Add, 200);
console.log('Performed math operation on money.');
// Just wanna make sure how much money I got
console.log('Current money:', await db.get('money'));
// RIP iron hide, he died
await db.remove('transformers', 'iron hide');
console.log('Removed iron hide from transformers:', await db.get('transformers'));
// I'm getting bored, so I'm clearing the whole database
await db.clear();
console.log('Cleared database.');
console.log('All data after clear:', await db.all());
}
runExample().catch(console.error);