Comparing version 1.0.0 to 2.0.0
@@ -6,21 +6,21 @@ # Examples | ||
```js | ||
const low = require('lowdb') | ||
const FileSync = require('lowdb/adapters/FileSync') | ||
// cli.js | ||
import { LowSync, JSONFileSync } from 'lowdb' | ||
const adapter = new FileSync('db.json') | ||
const db = low(adapter) | ||
const title = process.argv[2] | ||
const adapter = new FileSync('file.json') | ||
const db = new LowSync(adapter) | ||
db.defaults({ posts: [] }) | ||
.write() | ||
db.read() | ||
db.data ||= { posts: [] } | ||
const result = db.get('posts') | ||
.push({ name: process.argv[2] }) | ||
.write() | ||
db.data.posts.push({ title }) | ||
console.log(result) | ||
db.write() | ||
``` | ||
```sh | ||
$ node cli.js hello | ||
# [ { title: 'hello' } ] | ||
$ node cli.js "hello world" | ||
$ cat file.json | ||
# { "posts": [ "title": "hello world" ] } | ||
``` | ||
@@ -31,15 +31,13 @@ | ||
```js | ||
import low from 'lowdb' | ||
import LocalStorage from 'lowdb/adapters/LocalStorage' | ||
import { LowSync, LocalStorage } from 'lowdb' | ||
const adapter = new LocalStorage('db') | ||
const db = low(adapter) | ||
const db = new LowSync(adapter) | ||
db.defaults({ posts: [] }) | ||
.write() | ||
db.read() | ||
db.data ||= { posts: [] } | ||
// Data is automatically saved to localStorage | ||
db.get('posts') | ||
.push({ title: 'lowdb' }) | ||
.write() | ||
db.data.posts.push({ title: 'lowdb' }) | ||
db.write() | ||
``` | ||
@@ -49,44 +47,34 @@ | ||
Please __note__ that if you're developing a local server and don't expect to get concurrent requests, it's often easier to use `file-sync` storage, which is the default. | ||
**Note** if you're developing a local server and don't expect to get concurrent requests, it can be easier to use `JSONFileSync` adapter. | ||
But if you need to avoid blocking requests, you can do so by using `file-async` storage. | ||
But if you need to avoid blocking requests, you can do so by using `JSONFile` adapter. | ||
```js | ||
const express = require('express') | ||
const low = require('lowdb') | ||
const FileAsync = require('lowdb/adapters/FileAsync') | ||
import express from 'express' | ||
import { Low, JSONFile } from 'lowdb' | ||
// Create server | ||
const app = express() | ||
app.use(express.json()) | ||
// Routes | ||
// GET /posts/:id | ||
app.get('/posts/:id', (req, res) => { | ||
const post = db.get('posts') | ||
.find({ id: req.params.id }) | ||
.value() | ||
const adapter = new JSONFile('db.json') | ||
const db = new Low(adapter) | ||
await db.read() | ||
db.data ||= { posts: [] } | ||
const { posts } = db.data | ||
app.get('/posts/:id', async (req, res) => { | ||
const post = posts.find((p) => p.id === req.params.id) | ||
res.send(post) | ||
}) | ||
// POST /posts | ||
app.post('/posts', (req, res) => { | ||
db.get('posts') | ||
.push(req.body) | ||
.last() | ||
.assign({ id: Date.now() }) | ||
.write() | ||
.then(post => res.send(post)) | ||
app.post('/posts', async (req, res, next) => { | ||
const post = posts.push(req.body) | ||
await db.write() | ||
res.send(post) | ||
}) | ||
// Create database instance and start server | ||
const adapter = new FileAsync('db.json') | ||
low(adapter) | ||
.then(db => { | ||
db.defaults({ posts: [] }) | ||
.write() | ||
}) | ||
.then(() => { | ||
app.listen(3000, () => console.log('listening on port 3000') | ||
}) | ||
app.listen(3000, () => { | ||
console.log('listening on port 3000') | ||
}) | ||
``` | ||
@@ -100,18 +88,10 @@ | ||
const fs = require('fs') | ||
const low = require('low') | ||
const FileSync = require('low/adapters/FileSync') | ||
const Memory = require('low/adapters/Memory') | ||
const low = require('lowdb/lib/LowSync') | ||
const FileSync = require('lowdb/lib/adapters/FileSync') | ||
const MemorySync = require('lowdb/lib/adapters/MemorySync') | ||
const db = low( | ||
process.env.NODE_ENV === 'test' | ||
? new Memory() | ||
: new FileSync('db.json') | ||
) | ||
const adapter = | ||
process.env.NODE_ENV === 'test' ? new MemorySync() : new FileSync('db.json') | ||
db.defaults({ posts: [] }) | ||
.write() | ||
db.get('posts') | ||
.push({ title: 'lowdb' }) | ||
.write() | ||
const db = new LowSync(adapter) | ||
``` |
110
package.json
{ | ||
"name": "lowdb", | ||
"version": "1.0.0", | ||
"description": "Small JSON database for Node, Electron and the browser. Powered by Lodash.", | ||
"version": "2.0.0", | ||
"description": "Tiny local JSON database for Node, Electron and the browser", | ||
"type": "module", | ||
"exports": "./lib/index.js", | ||
"directories": { | ||
"example": "examples" | ||
}, | ||
"scripts": { | ||
"test": "jest --config .jestrc.json", | ||
"lint": "eslint src --ext .ts --ignore-path .gitignore", | ||
"build": "del-cli lib && tsc", | ||
"prepublishOnly": "npm run build", | ||
"postversion": "git push && git push --tags && npm publish", | ||
"prepare": "husky install" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/typicode/lowdb.git" | ||
}, | ||
"keywords": [ | ||
"flat", | ||
"file", | ||
"local", | ||
"database", | ||
"storage", | ||
"JSON", | ||
"lodash", | ||
"localStorage", | ||
"electron", | ||
"embed", | ||
"embeddable" | ||
"embedded", | ||
"flat", | ||
"JSON", | ||
"local", | ||
"localStorage" | ||
], | ||
"main": "./lib/main.js", | ||
"scripts": { | ||
"test": "jest && npm run lint", | ||
"lint": "eslint . --ignore-path .gitignore", | ||
"fix": "npm run lint -- --fix", | ||
"prepublishOnly": "npm run build && pkg-ok", | ||
"build": "npm run build:lib && npm run build:dist", | ||
"build:lib": "rimraf lib && babel src --out-dir lib && npm run mvAdapters", | ||
"build:dist": "rimraf dist && webpack && webpack -p", | ||
"mvAdapters": "rimraf adapters && mv lib/adapters .", | ||
"precommit": "npm test" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/typicode/lowdb.git" | ||
}, | ||
"author": "Typicode <typicode@gmail.com>", | ||
"license": "MIT", | ||
"license": "Parity-7.0.0 AND MIT WITH Patron-1.0.0", | ||
"bugs": { | ||
"url": "https://github.com/typicode/lowdb/issues" | ||
}, | ||
"homepage": "https://github.com/typicode/lowdb", | ||
"homepage": "https://github.com/typicode/lowdb#readme", | ||
"devDependencies": { | ||
"@commitlint/cli": "^12.0.1", | ||
"@commitlint/config-conventional": "^12.0.1", | ||
"@commitlint/prompt-cli": "^12.0.1", | ||
"@tsconfig/node12": "^1.0.7", | ||
"@types/jest": "^26.0.20", | ||
"@types/lodash": "^4.14.168", | ||
"@types/node": "^15.0.3", | ||
"@typicode/eslint-config": "^0.1.0", | ||
"del-cli": "^3.0.1", | ||
"husky": "^6.0.0", | ||
"jest": "^26.6.3", | ||
"jest-localstorage-mock": "^2.4.8", | ||
"lodash": "^4.17.21", | ||
"tempy": "^1.0.1", | ||
"ts-jest": "^26.5.3", | ||
"typescript": "^4.2.3" | ||
}, | ||
"dependencies": { | ||
"graceful-fs": "^4.1.3", | ||
"is-promise": "^2.1.0", | ||
"lodash": "4", | ||
"pify": "^3.0.0", | ||
"steno": "^0.4.1" | ||
"steno": "^1.0.0" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "^6.2.0", | ||
"babel-eslint": "^7.0.0", | ||
"babel-jest": "^20.0.3", | ||
"babel-loader": "^7.1.1", | ||
"babel-polyfill": "^6.9.1", | ||
"babel-preset-env": "^1.6.0", | ||
"babel-register": "^6.9.0", | ||
"delay": "^2.0.0", | ||
"eslint": "^4.5.0", | ||
"eslint-config-prettier": "^2.3.0", | ||
"eslint-config-standard": "^10.2.1", | ||
"eslint-plugin-import": "^2.6.1", | ||
"eslint-plugin-node": "^5.1.0", | ||
"eslint-plugin-prettier": "^2.1.2", | ||
"eslint-plugin-promise": "^3.5.0", | ||
"eslint-plugin-standard": "^3.0.1", | ||
"husky": "^0.14.3", | ||
"jest": "^20.0.4", | ||
"lodash-id": "^0.14.0", | ||
"mv": "^2.1.1", | ||
"pkg-ok": "^1.0.1", | ||
"prettier": "^1.5.2", | ||
"ramda": "^0.24.1", | ||
"regenerator-runtime": "^0.11.0", | ||
"rimraf": "^2.5.4", | ||
"sinon": "^3.2.1", | ||
"tempfile": "^2.0.0", | ||
"webpack": "^3.3.0" | ||
}, | ||
"engines": { | ||
"node": ">=4" | ||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0" | ||
} | ||
} |
415
README.md
@@ -1,75 +0,46 @@ | ||
# Lowdb | ||
# lowdb | ||
[![](http://img.shields.io/npm/dm/lowdb.svg?style=flat)](https://www.npmjs.org/package/lowdb) [![NPM version](https://badge.fury.io/js/lowdb.svg)](http://badge.fury.io/js/lowdb) [![Build Status](https://travis-ci.org/typicode/lowdb.svg?branch=master)](https://travis-ci.org/typicode/lowdb) [![Donate](https://img.shields.io/badge/patreon-donate-ff69b4.svg)](https://www.patreon.com/typicode) | ||
> Tiny local JSON database for small projects 🦉 | ||
> Small JSON database for Node, Electron and the browser. Powered by Lodash. :zap: | ||
```js | ||
db.get('posts') | ||
.push({ id: 1, title: 'lowdb is awesome'}) | ||
.write() | ||
db.data.posts.push({ id: 1, title: 'lowdb is awesome' }) | ||
db.write() | ||
``` | ||
## Usage | ||
```sh | ||
npm install lowdb | ||
```js | ||
// db.json | ||
{ | ||
"posts": [ | ||
{ "id": 1, "title": "lowdb is awesome" } | ||
] | ||
} | ||
``` | ||
```js | ||
const low = require('lowdb') | ||
const FileSync = require('lowdb/adapters/FileSync') | ||
## Free for Open Source | ||
const adapter = new FileSync('db.json') | ||
const db = low(adapter) | ||
To help with OSS funding, lowdb v2 is released under Parity license for a limited time. It'll be released under MIT license once the __goal of 100 [sponsors](https://github.com/sponsors/typicode)__ is reached (currently at 55) or in five months. | ||
// Set some defaults | ||
db.defaults({ posts: [], user: {} }) | ||
.write() | ||
Meanwhile, lowdb v2 can be freely used in Open Source projects. Sponsors can use it in any type of project. | ||
// Add a post | ||
db.get('posts') | ||
.push({ id: 1, title: 'lowdb is awesome'}) | ||
.write() | ||
If you've installed this new version without knowing about the license change, you're excused for 30 days. There's also a 30 days trial. See license files for more details. | ||
// Set a user using Lodash shorthand syntax | ||
db.set('user.name', 'typicode') | ||
.write() | ||
``` | ||
Thank you for your support! | ||
Data is saved to `db.json` | ||
__Note:__ if you're already sponsoring [husky](https://github.com/typicode/husky), you can use lowdb v2 today :) | ||
```json | ||
{ | ||
"posts": [ | ||
{ "id": 1, "title": "lowdb is awesome"} | ||
], | ||
"user": { | ||
"name": "typicode" | ||
} | ||
} | ||
``` | ||
## Companies | ||
You can use any [lodash](https://lodash.com/docs) function like [`_.get`](https://lodash.com/docs#get) and [`_.find`](https://lodash.com/docs#find) with shorthand syntax. | ||
[Become a sponsor and have your company logo here](https://github.com/sponsors/typicode). | ||
```js | ||
// Use .value() instead of .write() if you're only reading from db | ||
db.get('posts') | ||
.find({ id: 1 }) | ||
.value() | ||
``` | ||
## Features | ||
Lowdb is perfect for CLIs, small servers, Electron apps and npm packages in general. | ||
- __Lightweight__ | ||
- __Minimalist__ and easy to learn API | ||
- Query and modify data using __plain JS__ | ||
- Improved __TypeScript__ support | ||
- Atomic write | ||
- Hackable: | ||
- Change storage, file format (JSON, YAML, ...) or add encryption via [adapters](#adapters) | ||
- Add lodash, ramda, ... for super powers! | ||
It supports __Node__, the __browser__ and uses __lodash API__, so it's very simple to learn. Actually, if you know Lodash, you already know how to use lowdb :wink: | ||
* [Usage examples](https://github.com/typicode/lowdb/tree/master/examples) | ||
* [CLI](https://github.com/typicode/lowdb/tree/master/examples#cli) | ||
* [Browser](https://github.com/typicode/lowdb/tree/master/examples#browser) | ||
* [Server](https://github.com/typicode/lowdb/tree/master/examples#server) | ||
* [In-memory](https://github.com/typicode/lowdb/tree/master/examples#in-memory) | ||
* [JSFiddle live example](https://jsfiddle.net/typicode/4kd7xxbu/) | ||
__Important__ lowdb doesn't support Cluster and may have issues with very large JSON files (~200MB). | ||
## Install | ||
@@ -81,304 +52,232 @@ | ||
Alternatively, if you're using [yarn](https://yarnpkg.com/) | ||
## Usage | ||
```sh | ||
yarn add lowdb | ||
``` | ||
```js | ||
import { join } from 'path' | ||
import { Low, JSONFile } from 'lowdb' | ||
A UMD build is also available on [unpkg](https://unpkg.com/) for testing and quick prototyping: | ||
// Use JSON file for storage | ||
const file = join(__dirname, 'db.json') | ||
const adapter = new JSONFile(file) | ||
const db = new Low(adapter) | ||
```html | ||
<script src="https://unpkg.com/lodash@4/lodash.min.js"></script> | ||
<script src="https://unpkg.com/lowdb@0.17/dist/low.min.js"></script> | ||
<script src="https://unpkg.com/lowdb@0.17/dist/LocalStorage.min.js"></script> | ||
<script> | ||
var adapter = new LocalStorage('db') | ||
var db = low(adapter) | ||
</script> | ||
``` | ||
// Read data from JSON file, this will set db.data content | ||
await db.read() | ||
## API | ||
// If file.json doesn't exist, db.data will be null | ||
// Set default data | ||
db.data ||= { posts: [] } | ||
__low(adapter)__ | ||
// Create and query items using plain JS | ||
db.data.posts.push('hello world') | ||
db.data.posts[0] | ||
Returns a lodash [chain](https://lodash.com/docs/4.17.4#chain) with additional properties and functions described below. | ||
// You can also use this syntax if you prefer | ||
const { posts } = db.data | ||
posts.push('hello world') | ||
__db.[...].write()__ | ||
// Write db.data content to db.json | ||
await db.write() | ||
``` | ||
__db.[...].value()__ | ||
```js | ||
// db.json | ||
{ | ||
"posts": [ "hello world" ] | ||
} | ||
``` | ||
`write()` is syntactic sugar for calling `value()` and `db.write()` in one line. | ||
### TypeScript | ||
On the other hand, `value()` is just [\_.protoype.value()](https://lodash.com/docs/4.17.4#prototype-value) and should be used to execute a chain that doesn't change database state. | ||
Lowdb now comes with TypeScript support. You can even type `db.data` content. | ||
```ts | ||
type Data = { | ||
posts: string[] // Expect posts to be an array of strings | ||
} | ||
const db = new Low<Data>(adapter) | ||
```js | ||
db.set('user.name', 'typicode') | ||
.write() | ||
// is equivalent to | ||
db.set('user.name', 'typicode') | ||
.value() | ||
db.write() | ||
db.data | ||
.posts | ||
.push(1) // TypeScript error 🎉 | ||
``` | ||
__db.___ | ||
### Lodash | ||
Database lodash instance. Use it to add your own utility functions or third-party mixins like [underscore-contrib](https://github.com/documentcloud/underscore-contrib) or [lodash-id](https://github.com/typicode/lodash-id). | ||
You can easily add lodash or other utility libraries to improve lowdb. | ||
```js | ||
db._.mixin({ | ||
second: function(array) { | ||
return array[1] | ||
} | ||
}) | ||
import lodash from lodash | ||
db.get('posts') | ||
.second() | ||
// ... | ||
// Note: db.data needs to be initialized before lodash.chain is called. | ||
db.chain = lodash.chain(db.data) | ||
// Instead of db.data, you can now use db.chain if you want to use the powerful API that lodash provides | ||
const post = db.chain | ||
.get('posts') | ||
.find({ id: 1 }) | ||
.value() | ||
``` | ||
__db.getState()__ | ||
### More examples | ||
Returns database state. | ||
For CLI, server and browser usage, see [`examples/`](/examples) directory. | ||
```js | ||
db.getState() // { posts: [ ... ] } | ||
``` | ||
## API | ||
__db.setState(newState)__ | ||
### Classes | ||
Replaces database state. | ||
Lowdb has two classes (for asynchronous and synchronous adapters). | ||
```js | ||
const newState = {} | ||
db.setState(newState) | ||
``` | ||
#### `new Low(adapter)` | ||
__db.write()__ | ||
Persists database using `adapter.write` (depending on the adapter, may return a promise). | ||
```js | ||
// With lowdb/adapters/FileSync | ||
db.write() | ||
console.log('State has been saved') | ||
import { Low, JSONFile } from 'lowdb' | ||
// With lowdb/adapters/FileAsync | ||
db.write() | ||
.then(() => console.log('State has been saved')) | ||
const db = new Low(new JSONFile('file.json')) | ||
await db.read() | ||
await db.write() | ||
``` | ||
__db.read()__ | ||
#### `new LowSync(adapterSync)` | ||
Reads source using `storage.read` option (depending on the adapter, may return a promise). | ||
```js | ||
import { LowSync, JSONFileSync } from 'lowdb' | ||
```js | ||
// With lowdb/FileSync | ||
const db = new LowSync(new JSONFileSync('file.json')) | ||
db.read() | ||
console.log('State has been updated') | ||
// With lowdb/FileAsync | ||
db.write() | ||
.then(() => console.log('State has been updated')) | ||
``` | ||
## Adapters API | ||
### Methods | ||
Please note this only applies to adapters bundled with Lowdb. Third-party adapters may have different options. | ||
#### `db.read()` | ||
For convenience, `FileSync`, `FileAsync` and `LocalBrowser` accept the following options: | ||
Calls `adaper.read()` and sets `db.data`. | ||
* __defaultValue__ if file doesn't exist, this value will be used to set the initial state (default: `{}`) | ||
* __serialize/deserialize__ functions used before writing and after reading (default: `JSON.stringify` and `JSON.parse`) | ||
**Note:** `JSONFile` and `JSONFileSync` adapters will set `db.data` to `null` if file doesn't exist. | ||
```js | ||
const adapter = new FileSync('array.yaml', { | ||
defaultValue: [], | ||
serialize: (array) => toYamlString(array), | ||
deserialize: (string) => fromYamlString(string) | ||
}) | ||
db.data // === null | ||
db.read() | ||
db.data // !== null | ||
``` | ||
## Guide | ||
#### `db.write()` | ||
### How to query | ||
Calls `adapter.write(db.data)`. | ||
With lowdb, you get access to the entire [lodash API](http://lodash.com/), so there are many ways to query and manipulate data. Here are a few examples to get you started. | ||
Please note that data is returned by reference, this means that modifications to returned objects may change the database. To avoid such behaviour, you need to use `.cloneDeep()`. | ||
Also, the execution of methods is lazy, that is, execution is deferred until `.value()` or `.write()` is called. | ||
#### Examples | ||
Check if posts exists. | ||
```js | ||
db.has('posts') | ||
.value() | ||
db.data = { posts: [] } | ||
db.write() // file.json will be { posts: [] } | ||
db.data = {} | ||
db.write() // file.json will be {} | ||
``` | ||
Set posts. | ||
### Properties | ||
```js | ||
db.set('posts', []) | ||
.write() | ||
``` | ||
#### `db.data` | ||
Holds your db content. If you're using the adapters coming with lowdb, it can be any type supported by [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). | ||
Sort the top five posts. | ||
For example: | ||
```js | ||
db.get('posts') | ||
.filter({published: true}) | ||
.sortBy('views') | ||
.take(5) | ||
.value() | ||
db.data = 'string' | ||
db.data = [1, 2, 3] | ||
db.data = { key: 'value' } | ||
``` | ||
Get post titles. | ||
## Adapters | ||
```js | ||
db.get('posts') | ||
.map('title') | ||
.value() | ||
``` | ||
### Lowdb adapters | ||
Get the number of posts. | ||
#### `JSONFile` `JSONFileSync` | ||
Adapters for reading and writing JSON files. | ||
```js | ||
db.get('posts') | ||
.size() | ||
.value() | ||
new Low(new JSONFile(filename)) | ||
new LowSync(new JSONFileSync(filename)) | ||
``` | ||
Get the title of first post using a path. | ||
#### `Memory` `MemorySync` | ||
```js | ||
db.get('posts[0].title') | ||
.value() | ||
``` | ||
In-memory adapters. Useful for speeding up unit tests. | ||
Update a post. | ||
```js | ||
db.get('posts') | ||
.find({ title: 'low!' }) | ||
.assign({ title: 'hi!'}) | ||
.write() | ||
new Low(new Memory()) | ||
new LowSync(new MemorySync()) | ||
``` | ||
Remove posts. | ||
#### `LocalStorage` | ||
```js | ||
db.get('posts') | ||
.remove({ title: 'low!' }) | ||
.write() | ||
``` | ||
Synchronous adapter for `window.localStorage`. | ||
Remove a property. | ||
```js | ||
db.unset('user.name') | ||
.write() | ||
new LowSync(new LocalStorage()) | ||
``` | ||
Make a deep clone of posts. | ||
### Third-party adapters | ||
```js | ||
db.get('posts') | ||
.cloneDeep() | ||
.value() | ||
``` | ||
If you've published an adapter for lowdb, feel free to create a PR to add it here. | ||
### How to use id based resources | ||
### Writing your own adapter | ||
Being able to get data using an id can be quite useful, particularly in servers. To add id-based resources support to lowdb, you have 2 options. | ||
You may want to create an adapter to write `db.data` to YAML, XML, ... or encrypt data. | ||
[shortid](https://github.com/dylang/shortid) is more minimalist and returns a unique id that you can use when creating resources. | ||
An adapter is a simple class that just needs to expose two methods: | ||
```js | ||
const shortid = require('shortid') | ||
class AsyncAdapter { | ||
read() { /* ... */ } // should return Promise<data> | ||
write(data) { /* ... */ } // should return Promise<void> | ||
} | ||
const postId = db | ||
.get('posts') | ||
.push({ id: shortid.generate(), title: 'low!' }) | ||
.write() | ||
.id | ||
const post = db | ||
.get('posts') | ||
.find({ id: postId }) | ||
.value() | ||
class SyncAdapter { | ||
read() { /* ... */ } // data | ||
write(data) { /* ... */ } // void | ||
} | ||
``` | ||
[lodash-id](https://github.com/typicode/lodash-id) provides a set of helpers for creating and manipulating id-based resources. | ||
For example, let's say you have some async storage and want to create an adapter for it: | ||
```js | ||
const lodashId = require('lodash-id') | ||
const db = low('db.json') | ||
import { api } from './AsyncStorage' | ||
db._.mixin(lodashId) | ||
const post = db | ||
.get('posts') | ||
.insert({ title: 'low!' }) | ||
.write() | ||
const post = db | ||
.get('posts') | ||
.getById(post.id) | ||
.value() | ||
``` | ||
### How to create custom adapters | ||
`low()` accepts custom Adapter, so you can virtually save your data to any storage using any format. | ||
```js | ||
class MyStorage { | ||
constructor() { | ||
class CustomAsyncAdapter { | ||
// Optional: your adapter can take arguments | ||
constructor(args) { | ||
// ... | ||
} | ||
read() { | ||
// Should return data (object or array) or a Promise | ||
async read() { | ||
const data = await api.read() | ||
return data | ||
} | ||
write(data) { | ||
// Should return nothing or a Promise | ||
async write(data) { | ||
await api.write(data) | ||
} | ||
} | ||
const adapter = new MyStorage(args) | ||
const db = low() | ||
const adapter = new CustomAsyncAdapter() | ||
const db = new Low(adapter) | ||
``` | ||
See [src/adapters](src/adapters) for examples. | ||
See [`src/adapters/`](src/adapters) for more examples. | ||
### How to encrypt data | ||
## Limits | ||
`FileSync`, `FileAsync` and `LocalStorage` accept custom `serialize` and `deserialize` functions. You can use them to add encryption logic. | ||
Lowdb doesn't support Node's cluster module. | ||
```js | ||
const adapter = new FileSync('db.json', { | ||
serialize: (data) => encrypt(JSON.stringify(data)) | ||
deserialize: (data) => JSON.parse(decrypt(data)) | ||
}) | ||
``` | ||
If you have large JavaScript objects (`~10-100MB`) you may hit some performance issues. This is because whenever you call `db.write`, the whole `db.data` is serialized and written to storage. | ||
## Changelog | ||
Depending on your use case, this can be fine or not. It can be mitigated by doing batch operations and calling `db.write` only when you need it. | ||
See changes for each version in the [release notes](https://github.com/typicode/lowdb/releases). | ||
If you plan to scale, it's highly recommended to use databases like PostgreSQL, MongoDB, ... | ||
## Limits | ||
Lowdb is a convenient method for storing data without setting up a database server. It is fast enough and safe to be used as an embedded database. | ||
However, if you seek high performance and scalability more than simplicity, you should probably stick to traditional databases like MongoDB. | ||
## License | ||
MIT - [Typicode :cactus:](https://github.com/typicode) | ||
[License Zero Parity 7.0.0](https://paritylicense.com/versions/7.0.0.html) and MIT (contributions) with exception [License Zero Patron 1.0.0](https://patronlicense.com/versions/1.0.0). |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Copyleft License
License(Experimental) Copyleft license information was found.
Found 1 instance in 1 package
License exception
License(Experimental) Contains an SPDX license exception.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
Non-permissive License
License(Experimental) A license not known to be considered permissive was found.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1
16
33
Yes
28798
6
70
362
283
1
+ Addedsteno@1.0.0(transitive)
- Removedgraceful-fs@^4.1.3
- Removedis-promise@^2.1.0
- Removedlodash@4
- Removedpify@^3.0.0
- Removedgraceful-fs@4.2.11(transitive)
- Removedis-promise@2.2.2(transitive)
- Removedlodash@4.17.21(transitive)
- Removedpify@3.0.0(transitive)
- Removedsteno@0.4.4(transitive)
Updatedsteno@^1.0.0