Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

level-js

Package Overview
Dependencies
Maintainers
7
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

level-js - npm Package Compare versions

Comparing version 3.0.0-rc1 to 3.0.0

CHANGELOG.md

80

index.js

@@ -0,1 +1,3 @@

/* global indexedDB */
'use strict'

@@ -6,6 +8,5 @@

var AbstractLevelDOWN = require('abstract-leveldown').AbstractLevelDOWN
var util = require('util')
var inherits = require('inherits')
var Iterator = require('./iterator')
var mixedToBuffer = require('./util/mixed-to-buffer')
var isDataCloneError = require('./util/is-data-clone-error')
var setImmediate = require('./util/immediate')

@@ -25,3 +26,3 @@ var support = require('./util/support')

util.inherits(Level, AbstractLevelDOWN)
inherits(Level, AbstractLevelDOWN)

@@ -74,3 +75,13 @@ // Detect binary and array key support (IndexedDB Second Edition)

Level.prototype._get = function (key, options, callback) {
this.await(this.store('readonly').get(key), function (err, value) {
var store = this.store('readonly')
try {
var req = store.get(key)
} catch (err) {
return setImmediate(function () {
callback(err)
})
}
this.await(req, function (err, value) {
if (err) return callback(err)

@@ -91,4 +102,14 @@

Level.prototype._del = function(key, options, callback) {
this.await(this.store('readwrite').delete(key), callback)
Level.prototype._del = function (key, options, callback) {
var store = this.store('readwrite')
try {
var req = store.delete(key)
} catch (err) {
return setImmediate(function () {
callback(err)
})
}
this.await(req, callback)
}

@@ -100,10 +121,6 @@

try {
// Will throw a DataCloneError if the environment
// does not support serializing the key or value.
// Will throw a DataError or DataCloneError if the environment
// does not support serializing the key or value respectively.
var req = store.put(value, key)
} catch (err) {
if (!isDataCloneError(err)) {
throw err
}
return setImmediate(function () {

@@ -122,4 +139,4 @@ callback(err)

// - String
// - ArrayBuffer or a view thereof (typed arrays). In level-js we only support
// Buffer (which is an Uint8Array).
// - ArrayBuffer or a view thereof (typed arrays). In level-js we also support
// Buffer (which is an Uint8Array) (and the primary binary type of Level).
// - Array, except cyclical and empty (e.g. Array(10)). Elements must be valid

@@ -132,7 +149,9 @@ // types themselves.

return Level.arrayKeys ? key.map(this._serializeKey, this) : String(key)
} else if ((typeof key === 'number' || key instanceof Date) && !isNaN(key)) {
} else if (typeof key === 'boolean' || (typeof key === 'number' && isNaN(key))) {
// These types are invalid per the IndexedDB spec and ideally we'd treat
// them that way, but they're valid per the current abstract test suite.
return String(key)
} else {
return key
}
return String(key)
}

@@ -154,5 +173,6 @@

var index = 0
var error
transaction.onabort = function () {
callback(transaction.error || new Error('aborted by user'))
callback(error || transaction.error || new Error('aborted by user'))
}

@@ -168,4 +188,11 @@

var key = op.key
var req = op.type === 'del' ? store.delete(key) : store.put(op.value, key)
try {
var req = op.type === 'del' ? store.delete(key) : store.put(op.value, key)
} catch (err) {
error = err
transaction.abort()
return
}
if (index < operations.length) {

@@ -181,20 +208,17 @@ req.onsuccess = loop

this.db.close()
callback()
setImmediate(callback)
}
Level.destroy = function (db, callback) {
if (typeof db === 'object') {
var prefix = db.prefix || DEFAULT_PREFIX
var location = db.location
} else {
Level.destroy = function (location, prefix, callback) {
if (typeof prefix === 'function') {
callback = prefix
prefix = DEFAULT_PREFIX
location = db
}
var request = indexedDB.deleteDatabase(prefix + location)
request.onsuccess = function() {
request.onsuccess = function () {
callback()
}
request.onerror = function(err) {
request.onerror = function (err) {
callback(err)
}
}

@@ -0,5 +1,7 @@

/* global IDBKeyRange */
'use strict'
var util = require('util')
var AbstractIterator = require('abstract-leveldown').AbstractIterator
var inherits = require('inherits')
var AbstractIterator = require('abstract-leveldown').AbstractIterator
var ltgt = require('ltgt')

@@ -44,3 +46,3 @@ var mixedToBuffer = require('./util/mixed-to-buffer')

util.inherits(Iterator, AbstractIterator)
inherits(Iterator, AbstractIterator)

@@ -121,3 +123,3 @@ Iterator.prototype.createKeyRange = function (options) {

setImmediate(function() {
setImmediate(function () {
callback(err)

@@ -132,3 +134,3 @@ })

setImmediate(function() {
setImmediate(function () {
callback(null, key, value)

@@ -135,0 +137,0 @@ })

# The MIT License (MIT)
## Copyright (c) 2012-2018 `level.js` contributors
**Copyright © 2012-present [Max Ogden](https://github.com/maxogden) and [Contributors](./CONTRIBUTORS.md).**
*`level.js` contributors listed at <https://github.com/level/community#contributors>*
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

@@ -8,0 +6,0 @@

{
"name": "level-js",
"version": "3.0.0-rc1",
"description": "leveldown/leveldb library for browsers using IndexedDB",
"version": "3.0.0",
"description": "An abstract-leveldown compliant store on top of IndexedDB",
"author": "max ogden",
"license": "MIT",
"main": "index.js",
"scripts": {
"test": "airtap --local --no-coverage test/index.js",
"test-browsers": "airtap --sauce-connect --loopback airtap.local --no-coverage test/index.js"
"test": "standard && airtap --local --no-coverage test/index.js",
"test-browsers": "standard && airtap --sauce-connect --loopback airtap.local --no-coverage test/index.js",
"remark": "remark README.md CONTRIBUTORS.md CHANGELOG.md UPGRADING.md -o"
},
"repository": {
"type": "git",
"url": "git@github.com:Level/level.js.git"
},
"keywords": [
"level",
"leveldb"
"files": [
"index.js",
"iterator.js",
"util",
"CONTRIBUTORS.md",
"CHANGELOG.md",
"UPGRADING.md",
"sauce-labs.svg"
],
"author": "max ogden",
"license": "MIT",
"devDependencies": {
"airtap": "0.0.7",
"browserify": "~16.2.2",
"encoding-down": "~5.0.2",
"levelup": "~3.0.0",
"pinkie": "~2.0.4",
"tape": "^4.0.0"
"browser": {
"./util/immediate.js": "./util/immediate-browser.js"
},
"standard": {
"ignore": [
"test/util/idb-shim.js"
]
},
"dependencies": {
"abstract-leveldown": "~5.0.0",
"immediate": "~3.2.3",
"inherits": "^2.0.3",
"ltgt": "^2.1.2",
"typedarray-to-buffer": "~3.1.5"
},
"browser": {
"./util/immediate.js": "./util/immediate-browser.js"
}
"devDependencies": {
"airtap": "0.0.7",
"buffer": "~5.1.0",
"level-community": "~3.0.0",
"remark-cli": "^5.0.0",
"remark-collapse": "~0.1.2",
"remark-git-contributors": "~0.2.1",
"remark-github": "~7.0.3",
"remark-toc": "~5.0.0",
"standard": "^11.0.1",
"tape": "^4.0.0"
},
"remarkConfig": {
"plugins": [
[
"remark-git-contributors",
"level-community"
],
[
"remark-github"
],
[
"remark-toc",
{
"maxDepth": 2,
"tight": true
}
],
[
"remark-collapse",
{
"test": "Table of Contents",
"summary": "Click to expand"
}
]
]
},
"repository": {
"type": "git",
"url": "https://github.com/Level/level-js.git"
},
"keywords": [
"level",
"leveldb",
"indexeddb",
"abstract-leveldown"
]
}
# level-js
> An [`abstract-leveldown`](https://github.com/Level/abstract-leveldown) compliant store on top of [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API), which is in turn implemented on top of [LevelDB](https://github.com/google/leveldb) which brings this whole shebang full circle.
> An [`abstract-leveldown`][abstract-leveldown] compliant store on top of [IndexedDB][indexeddb], which is in turn implemented on top of [LevelDB][leveldb] which brings this whole shebang full circle.
[![level badge][level-badge]](https://github.com/level/awesome)
[![level badge][level-badge]][awesome]
[![npm](https://img.shields.io/npm/v/level-js.svg)](https://www.npmjs.com/package/level-js)
[![npm next](https://img.shields.io/npm/v/level-js/next.svg)](https://www.npmjs.com/package/level-js)
[![Travis](https://secure.travis-ci.org/Level/level.js.svg?branch=master)](http://travis-ci.org/Level/level.js)
[![Travis](https://secure.travis-ci.org/Level/level-js.svg?branch=master)](http://travis-ci.org/Level/level-js)
[![npm](https://img.shields.io/npm/dm/level-js.svg)](https://www.npmjs.com/package/level-js)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
## Table of Contents
<details><summary>Click to expand</summary>
- [Background](#background)
- [Example](#example)
- [Browser Support](#browser-support)
- [Type Support](#type-support)
- [Install](#install)
- [API](#api)
- [Running Tests](#running-tests)
- [Big Thanks](#big-thanks)
- [License](#license)
</details>
## Background

@@ -15,15 +31,15 @@

- Store large amounts of data in modern browsers
- Pass the full `abstract-leveldown` test suite
- Support [Buffer](https://nodejs.org/api/buffer.html) values (in all target environments)
- Support all key types of IndexedDB Second Edition, including binary keys (depends on environment)
- Support all value types of the structured clone algorithm (depends on environment)
- Be as fast as possible
- Sync with [multilevel](https://github.com/juliangruber/multilevel) over either ASCII or binary transports.
- Store large amounts of data in modern browsers
- Pass the full [`abstract-leveldown`][abstract-leveldown] test suite
- Support [`Buffer`][buffer] keys and values
- Support all key types of IndexedDB Second Edition
- Support all value types of the [structured clone algorithm][structured-clone-algorithm] except for `null` and `undefined`
- Be as fast as possible
- Sync with [multilevel](https://github.com/juliangruber/multilevel) over ASCII or binary transports.
Being `abstract-leveldown` compliant means you can use many of the [Level modules](https://github.com/Level/awesome/) on top of this library. For some demos of it working, see @brycebaril's presentation [Path of the NodeBases Jedi](http://brycebaril.github.io/nodebase_jedi/#/vanilla).
Being `abstract-leveldown` compliant means you can use many of the [Level modules][awesome] on top of this library. For some demos of it working, see [**@brycebaril**](https://github.com/brycebaril)'s presentation [Path of the NodeBases Jedi](http://brycebaril.github.io/nodebase_jedi/#/vanilla).
## Example
**This assumes use of version `3.0.0-rc1`. The next release will have an upgrade guide.**
**If you are upgrading:** please see [UPGRADING.md](UPGRADING.md).

@@ -46,2 +62,13 @@ ```js

In ES6 browsers:
```js
const levelup = require('levelup')
const leveljs = require('level-js')
const db = levelup(leveljs('bigdata'))
await db.put('hello', Buffer.from('world'))
const value = await db.get('hello')
```
## Browser Support

@@ -51,7 +78,91 @@

## Type Support
Unlike [`leveldown`][leveldown], `level-js` does not stringify keys or values. This means that in addition to strings and Buffers you can store almost any JavaScript type without the need for [`encoding-down`][encoding-down].
### Values
All value types of the [structured clone algorithm][structured-clone-algorithm] are supported except for `null` and `undefined`. Depending on the environment, this includes:
- Number, including `NaN`, `Infinity` and `-Infinity`
- String, Boolean, Date, RegExp, Array, Object
- ArrayBuffer or a view thereof (typed arrays);
- Map, Set, Blob, File, FileList, ImageData (limited support).
In addition `level-js` stores [`Buffer`][buffer] values without transformation. This works in all target environments because `Buffer` is a subclass of `Uint8Array`, meaning such values can be passed to `IndexedDB` as-is.
When getting or iterating binary values, regardless of whether they were stored as a `Buffer`, `ArrayBuffer` or a view thereof, values will return as a `Buffer`. This behavior can be disabled, in which case `ArrayBuffer` returns as `ArrayBuffer`, typed arrays return as typed arrays and `Buffer` returns as `Uint8Array`:
```js
db.get('key', { asBuffer: false })
db.iterator({ valueAsBuffer: false })
```
If the environment does not support a type, it will throw an error which `level-js` catches and passes to the callbacks of `put` or `batch`. For example, IE does not support typed array values. At the time of writing, Chrome is the only browser that supports all types listed above.
Due to the special meaning that `null` and `undefined` have in `abstract-leveldown` iterators and Node.js streams, values of this type are converted to empty strings prior to storage.
### Keys
All key types of IndexedDB Second Edition are supported. Depending on the environment, this includes:
- Number, including `Infinity` and `-Infinity`, but not `NaN`
- Date, except invalid (`NaN`)
- String
- ArrayBuffer or a view thereof (typed arrays);
- Array, except cyclical, empty and sparse arrays. Elements must be valid types themselves.
In addition you can use [`Buffer`][buffer] keys, giving `level-js` the same power as implementations like `leveldown` and `memdown`. When iterating binary keys, regardless of whether they were stored as `Buffer`, `ArrayBuffer` or a view thereof, keys will return as a `Buffer`. This behavior can be disabled, in which case binary keys will always return as `ArrayBuffer`:
```js
db.iterator({ keyAsBuffer: false })
```
Note that this behavior is slightly different from values due to the way that IndexedDB works. IndexedDB stores binary _values_ using the structured clone algorithm, which preserves views, but it stores binary _keys_ as an array of octets, so that it is able to compare and sort differently typed keys.
If the environment does not support a type, it will throw an error which `level-js` catches and passes to the callbacks of `get`, `put`, `del`, `batch` or an iterator. Exceptions are:
- `null` and `undefined`: rejected early by `abstract-leveldown`
- Boolean and `NaN`: though invalid per the IndexedDB specification, they are converted to strings for `abstract-leveldown` compatibility;
- Binary and array keys: if not supported by the environment, `level-js` falls back to `String(key)`.
### Normalization
If you desire normalization for keys and values (e.g. to stringify numbers), wrap `level-js` with [`encoding-down`][encoding-down]. Alternatively install [`level-browserify`][level-browserify] which conveniently bundles [`levelup`][levelup], `level-js` and `encoding-down`. Such an approach is also recommended if you want to achieve universal (isomorphic) behavior or to smooth over type differences between browsers. For example, you could have [`leveldown`][leveldown] in a backend and `level-js` in the frontend.
Another reason you might want to use `encoding-down` is that the structured clone algorithm, while rich in types, can be slower than `JSON.stringify`.
### Buffer vs ArrayBuffer
For interoperability it is recommended to use `Buffer` as your binary type. While we recognize that Node.js core modules are moving towards supporting `ArrayBuffer` and views thereof, `Buffer` remains the primary binary type in the Level ecosystem.
That said: if you want to `put()` an `ArrayBuffer` you can! Just know that it will come back as a `Buffer` by default. If you want to `get()` or iterate stored `ArrayBuffer` data as an `ArrayBuffer`, you have a few options. Without `encoding-down`:
```js
const db = levelup(leveljs('mydb'))
// Yields an ArrayBuffer, Buffer and ArrayBuffer
const value1 = await db.get('key', { asBuffer: false })
const value2 = await db.get('key')
const value3 = value2.buffer
```
With `encoding-down` (or `level-browserify`) you can use the `id` encoding to selectively bypass encodings:
```js
const encode = require('encoding-down')
const db = levelup(encode(leveljs('mydb'), { valueEncoding: 'binary' }))
// Yields an ArrayBuffer, Buffer and ArrayBuffer
const value1 = await db.get('key', { valueEncoding: 'id' })
const value2 = await db.get('key')
const value3 = value2.buffer
```
## Install
With [npm](https://npmjs.org) do:
```bash
npm install level-js # Stable
npm install level-js@next # Bleeding edge
npm install level-js
```

@@ -63,7 +174,22 @@

## API
### `db = leveljs(location[, options])`
Returns a new `leveljs` instance. `location` is the string name of the [`IDBDatabase`](https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase) to be opened, as well as the object store within that database. The database name will be prefixed with `options.prefix`.
#### `options`
The optional `options` argument may contain:
- `prefix` _(string, default: `'level-js-'`)_: Prefix for `IDBDatabase` name.
- `version` _(string | number, default: `1`)_: The version to open the database with.
See [`IDBFactory#open`](https://developer.mozilla.org/en-US/docs/Web/API/IDBFactory/open) for more details.
## Running Tests
```sh
git clone git@github.com:Level/level.js.git
cd level.js
git clone git@github.com:Level/level-js.git
cd level-js
npm install

@@ -83,6 +209,24 @@ npm test

Copyright (c) 2012-2018 `level.js` [contributors](https://github.com/level/community#contributors).
[MIT](./LICENSE.md) © 2012-present [Max Ogden](https://github.com/maxogden) and [Contributors](./CONTRIBUTORS.md).
`level.js` is licensed under the MIT license. All rights not explicitly granted in the MIT license are reserved. See the included `LICENSE.md` file for more details.
[level-badge]: http://leveldb.org/img/badge.svg
[level-badge]: http://leveldb.org/img/badge.svg
[indexeddb]: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
[leveldb]: https://github.com/google/leveldb
[buffer]: https://nodejs.org/api/buffer.html
[awesome]: https://github.com/Level/awesome
[abstract-leveldown]: https://github.com/Level/abstract-leveldown
[levelup]: https://github.com/Level/levelup
[leveldown]: https://github.com/Level/leveldown
[level-browserify]: https://github.com/Level/level-browserify
[encoding-down]: https://github.com/Level/encoding-down
[structured-clone-algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm

@@ -7,3 +7,4 @@ 'use strict'

if (value instanceof Uint8Array) return toBuffer(value)
else if (value instanceof ArrayBuffer) return Buffer.from(value)
else return Buffer.from(String(value))
}
'use strict'
exports.binaryKeys = function (impl) {
try {
impl.cmp(new Uint8Array(0), 0)
return true
} catch (err) {
return false
exports.test = function (key) {
return function test (impl) {
try {
impl.cmp(key, 0)
return true
} catch (err) {
return false
}
}
}
exports.arrayKeys = function (impl) {
try {
impl.cmp([1], 0)
return true
} catch (err) {
return false
}
}
exports.binaryKeys = exports.test(new Uint8Array(0))
exports.arrayKeys = exports.test([1])
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc