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

localstorage-down

Package Overview
Dependencies
Maintainers
3
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

localstorage-down - npm Package Compare versions

Comparing version 0.5.2 to 0.6.0

localstorage-core.js

265

index.js
'use strict';
var util = require('util');
var inherits = require('inherits');
var AbstractLevelDOWN = require('abstract-leveldown').AbstractLevelDOWN;
var AbstractIterator = require('abstract-leveldown').AbstractIterator;
var noop = function () {
};
var LocalStorage = require('./localstorage').LocalStorage;
var LocalStorageCore = require('./localstorage-core');
// see http://stackoverflow.com/a/15349865/680742
var nextTick = global.setImmediate || process.nextTick;

@@ -14,6 +17,5 @@

this._dbsize = this.db.container.length();
this._reverse = !!options.reverse;
this._end = options.end;
this._start = options.start;
this._endkey = options.end;
this._startkey = options.start;
this._gt = options.gt;

@@ -27,44 +29,99 @@ this._gte = options.gte;

if (this._start) {
this._pos = this.db.container.indexOfKey(this._start);
if (this._reverse) {
if (this._exclusiveStart || this.db.container.key(this._pos) !== this._start) {
this._pos--;
}
} else if (this._exclusiveStart && this.db.container.key(this._pos) === this._start) {
this._pos++;
}
} else {
this._pos = this._reverse ? this._dbsize - 1 : 0;
}
this.onInitCompleteListeners = [];
}
util.inherits(LDIterator, AbstractIterator);
inherits(LDIterator, AbstractIterator);
LDIterator.prototype._init = function (callback) {
var self = this;
self.db.container.length(function (err, len) {
if (err) {
return callback(err);
}
if (self._startkey) {
self.db.container.binarySearch(self._startkey, function (err, res) {
if (err) {
return callback(err);
}
self._pos = res.index;
var startkey = res.key;
if (self._reverse) {
if (self._exclusiveStart || startkey !== self._startkey) {
self._pos--;
}
} else if (self._exclusiveStart && startkey === self._startkey) {
self._pos++;
}
callback();
});
} else {
self._pos = self._reverse ? len - 1 : 0;
callback();
}
});
};
LDIterator.prototype._next = function (callback) {
var self = this;
if (this._pos >= this.db.container.length() || this._pos < 0) {
return nextTick(callback);
}
var key = this.db.container.key(this._pos);
function onInitComplete() {
self.db.container.getKeyAt(self._pos, function (err, key) {
if (err) {
return callback(err);
}
if (!!this._end && (this._reverse ? key < this._end : key > this._end)) {
return nextTick(callback);
}
if (typeof key === 'undefined') { // done reading
return callback();
}
if (!!this._limit && this._limit > 0 && this._count++ >= this._limit) {
return nextTick(callback);
if (!!self._endkey && (self._reverse ? key < self._endkey : key > self._endkey)) {
return callback();
}
if (!!self._limit && self._limit > 0 && self._count++ >= self._limit) {
return callback();
}
if ((self._lt && key >= self._lt) ||
(self._lte && key > self._lte) ||
(self._gt && key <= self._gt) ||
(self._gte && key < self._gte)) {
return callback();
}
self._pos += self._reverse ? -1 : 1;
self.db.container.getItem(key, function (err, value) {
if (err) {
if (err.message === 'NotFound') {
return callback();
}
return callback(err);
}
callback(null, key, value);
});
});
}
if (!self.initStarted) {
self.initStarted = true;
self._init(function (err) {
if (err) {
return callback(err);
}
onInitComplete();
if ((this._lt && key >= this._lt) ||
(this._lte && key > this._lte) ||
(this._gt && key <= this._gt) ||
(this._gte && key < this._gte)) {
return nextTick(callback);
self.initCompleted = true;
var i = -1;
while (++i < self.onInitCompleteListeners) {
nextTick(self.onInitCompleteListeners[i]);
}
});
} else if (!self.initCompleted) {
self.onInitCompleteListeners.push(function () {
onInitComplete();
});
} else {
onInitComplete();
}
var value = this.db.container.getItem(key);
this._pos += this._reverse ? -1 : 1;
nextTick(function () { callback(null, key, value); });
};

@@ -77,12 +134,9 @@

AbstractLevelDOWN.call(this, location);
var Wstore = require('./localstorage').LocalStorage;
this.container = new Wstore(location);
this.container = new LocalStorage(location);
}
util.inherits(LD, AbstractLevelDOWN);
inherits(LD, AbstractLevelDOWN);
LD.prototype._open = function (options, callback) {
nextTick(function () {
callback(null, this);
}.bind(this));
this.container.init(callback);
};

@@ -95,3 +149,5 @@

if (err) {
return callback(err);
return nextTick(function () {
callback(err);
});
}

@@ -102,3 +158,5 @@

if (err) {
return callback(err);
return nextTick(function () {
callback(err);
});
}

@@ -113,4 +171,3 @@

this.container.setItem(key, value);
nextTick(callback);
this.container.setItem(key, value, callback);
};

@@ -123,3 +180,5 @@

if (err) {
return callback(err);
return nextTick(function () {
callback(err);
});
}

@@ -130,25 +189,19 @@

}
var value = this.container.getItem(key);
this.container.getItem(key, function (err, value) {
if (value === undefined) {
// 'NotFound' error, consistent with LevelDOWN API
return nextTick(function () {
callback(new Error('NotFound: '));
});
}
if (err) {
return callback(err);
}
if (options.asBuffer !== false && !Buffer.isBuffer(value)) {
value = new Buffer(value);
}
if (options.asBuffer !== false && !Buffer.isBuffer(value)) {
value = new Buffer(value);
}
if (options.asBuffer === false) {
if (value.indexOf("{\"storetype\":\"json\",\"data\"") > -1) {
var res = JSON.parse(value);
value = res.data;
if (options.asBuffer === false) {
if (value.indexOf("{\"storetype\":\"json\",\"data\"") > -1) {
var res = JSON.parse(value);
value = res.data;
}
}
}
nextTick(function () {
callback(null, value);

@@ -163,3 +216,5 @@ });

if (err) {
return callback(err);
return nextTick(function () {
callback(err);
});
}

@@ -170,33 +225,49 @@ if (!isBuffer(key)) {

this.container.removeItem(key);
nextTick(callback);
this.container.removeItem(key, callback);
};
LD.prototype._batch = function (array, options, callback) {
var err;
var i = 0;
var key;
var value;
if (Array.isArray(array)) {
for (; i < array.length; i++) {
if (array[i]) {
key = Buffer.isBuffer(array[i].key) ? array[i].key : String(array[i].key);
err = checkKeyValue(key, 'key');
if (err) {
return nextTick(callback.bind(null, err));
}
if (array[i].type === 'del') {
this._del(array[i].key, options, noop);
} else if (array[i].type === 'put') {
value = Buffer.isBuffer(array[i].value) ? array[i].value : String(array[i].value);
err = checkKeyValue(value, 'value');
var self = this;
nextTick(function () {
var err;
var key;
var value;
var numDone = 0;
var overallErr;
function checkDone() {
if (++numDone === array.length) {
callback(overallErr);
}
}
if (Array.isArray(array) && array.length) {
for (var i = 0; i < array.length; i++) {
var task = array[i];
if (task) {
key = Buffer.isBuffer(task.key) ? task.key : String(task.key);
err = checkKeyValue(key, 'key');
if (err) {
return nextTick(callback.bind(null, err));
overallErr = err;
checkDone();
} else if (task.type === 'del') {
self._del(task.key, options, checkDone);
} else if (task.type === 'put') {
value = Buffer.isBuffer(task.value) ? task.value : String(task.value);
err = checkKeyValue(value, 'value');
if (err) {
overallErr = err;
checkDone();
} else {
self._put(key, value, options, checkDone);
}
}
this._put(key, value, options, noop);
} else {
checkDone();
}
}
} else {
callback();
}
}
nextTick(callback);
});
};

@@ -209,13 +280,3 @@

LD.destroy = function (name, callback) {
try {
Object.keys(localStorage)
.forEach(function (key) {
if (key.substring(0, name.length + 1) === (name + "!")) {
localStorage.removeItem(key);
}
});
callback();
} catch (e) {
// fail gracefully if no LocalStorage
}
LocalStorageCore.destroy(name, callback);
};

@@ -222,0 +283,0 @@

@@ -9,84 +9,123 @@ 'use strict';

var utils = require('./utils');
var LocalStorageCore = require('./localstorage-core');
var TaskQueue = require('./taskqueue');
function LocalStorage(dbname) {
this._keys = [];
this._prefix = dbname.replace(/!/g, '!!') + '!'; // escape bangs in dbname
var prefixLen = this._prefix.length;
var i = -1;
var len = window.localStorage.length;
while (++i < len) {
var fullKey = window.localStorage.key(i);
if (fullKey.substring(0, prefixLen) === this._prefix) {
this._keys.push(fullKey.substring(prefixLen));
}
}
this._keys.sort();
this._store = new LocalStorageCore(dbname);
this._queue = new TaskQueue();
}
//key: Returns the name of the key at the position specified.
LocalStorage.prototype.key = function (keyindex) {
return this._keys[keyindex];
LocalStorage.prototype.sequentialize = function (callback, fun) {
this._queue.add(fun, callback);
};
LocalStorage.prototype.init = function (callback) {
var self = this;
self.sequentialize(callback, function (callback) {
self._store.getKeys(function (err, keys) {
if (err) {
return callback(err);
}
self._keys = keys;
return callback();
});
});
};
// returns the key index if found, else the index where
// the key should be inserted
LocalStorage.prototype.indexOfKey = function(key) {
return utils.sortedIndexOf(this._keys, key);
// the key should be inserted. also returns the key
// at that index
LocalStorage.prototype.binarySearch = function (key, callback) {
var self = this;
self.sequentialize(callback, function (callback) {
var index = utils.sortedIndexOf(self._keys, key);
var foundKey = (index >= self._keys.length || index < 0) ?
undefined : self._keys[index];
callback(null, {index: index, key: foundKey});
});
};
LocalStorage.prototype.getKeyAt = function (index, callback) {
var self = this;
self.sequentialize(callback, function (callback) {
var foundKey = (index >= self._keys.length || index < 0) ?
undefined : self._keys[index];
callback(null, foundKey);
});
};
//setItem: Saves and item at the key provided.
LocalStorage.prototype.setItem = function (key, value) {
if (value instanceof ArrayBuffer) {
value = arrayBuffPrefix + btoa(String.fromCharCode.apply(null, value));
} else if (value instanceof Uint8Array) {
value = uintPrefix + btoa(String.fromCharCode.apply(null, value));
}
LocalStorage.prototype.setItem = function (key, value, callback) {
var self = this;
self.sequentialize(callback, function (callback) {
if (value instanceof ArrayBuffer) {
value = arrayBuffPrefix + btoa(String.fromCharCode.apply(null, value));
} else if (value instanceof Uint8Array) {
value = uintPrefix + btoa(String.fromCharCode.apply(null, value));
}
var idx = utils.sortedIndexOf(this._keys, key);
if (this._keys[idx] !== key) {
this._keys.splice(idx, 0, key);
}
window.localStorage.setItem(this._prefix + key, value);
var idx = utils.sortedIndexOf(self._keys, key);
if (self._keys[idx] !== key) {
self._keys.splice(idx, 0, key);
}
self._store.put(key, value, callback);
});
};
//getItem: Returns the item identified by it's key.
LocalStorage.prototype.getItem = function (key) {
var value;
var retval = window.localStorage.getItem(this._prefix + key);
if (retval == null) {
return undefined;
}
if (arrayBuffRegex.test(retval)) {
value = retval.substring(arrayBuffPrefix.length);
retval = new ArrayBuffer(atob(value).split('').map(function (c) {
return c.charCodeAt(0);
}));
return retval;
} else if (uintRegex.test(retval)) {
value = retval.substring(uintPrefix.length);
retval = new Uint8Array(atob(value).split('').map(function (c) {
return c.charCodeAt(0);
}));
return retval;
}
return retval;
LocalStorage.prototype.getItem = function (key, callback) {
var self = this;
self.sequentialize(callback, function (callback) {
self._store.get(key, function (err, retval) {
if (err) {
return callback(err);
}
if (typeof retval === 'undefined' || retval === null) {
// 'NotFound' error, consistent with LevelDOWN API
return callback(new Error('NotFound'));
}
if (typeof retval !== 'undefined') {
if (arrayBuffRegex.test(retval)) {
retval = retval.substring(arrayBuffPrefix.length);
retval = new ArrayBuffer(atob(retval).split('').map(function (c) {
return c.charCodeAt(0);
}));
} else if (uintRegex.test(retval)) {
retval = retval.substring(uintPrefix.length);
retval = new Uint8Array(atob(retval).split('').map(function (c) {
return c.charCodeAt(0);
}));
}
}
callback(null, retval);
});
});
};
//removeItem: Removes the item identified by it's key.
LocalStorage.prototype.removeItem = function (key) {
var idx = utils.sortedIndexOf(this._keys, key);
if (this._keys[idx] === key) {
this._keys.splice(idx, 1);
window.localStorage.removeItem(this._prefix + key);
}
LocalStorage.prototype.removeItem = function (key, callback) {
var self = this;
self.sequentialize(callback, function (callback) {
var idx = utils.sortedIndexOf(self._keys, key);
if (self._keys[idx] === key) {
self._keys.splice(idx, 1);
self._store.remove(key, function (err) {
if (err) {
return callback(err);
}
callback();
});
} else {
callback();
}
});
};
LocalStorage.prototype.length = function () {
return this._keys.length;
LocalStorage.prototype.length = function (callback) {
var self = this;
self.sequentialize(callback, function (callback) {
callback(null, self._keys.length);
});
};
exports.LocalStorage = LocalStorage;

@@ -15,6 +15,9 @@ {

],
"version": "0.5.2",
"version": "0.6.0",
"main": "index.js",
"dependencies": {
"abstract-leveldown": "~0.12.0"
"abstract-leveldown": "~0.12.0",
"argsarray": "0.0.1",
"inherits": "^2.0.1",
"tiny-queue": "0.2.0"
},

@@ -44,19 +47,13 @@ "devDependencies": {

"browsers": [
"iexplore/10.0",
"chrome/30.0",
"chrome/31.0",
"firefox/25.0",
"firefox/24.0",
"opera/15.0",
"opera/16.0",
"opera/17.0",
"safari/5.0.5",
"safari/5.1",
"iexplore/8..latest",
"chrome/22..latest",
"chrome/canary",
"firefox/24..latest",
"firefox/nightly",
"opera/15..latest",
"opera/next",
"chrome/canary",
"iphone/6.0",
"ipad/6.0",
"safari/6.0",
"android-browser/4.2"
"safari/5.0.5..latest",
"iphone/latest",
"ipad/latest",
"android-browser/latest"
]

@@ -63,0 +60,0 @@ },

@@ -25,2 +25,9 @@ # localstorage-down

## Browser support
Basically we support [any browser that has localStorage](http://caniuse.com/namevalue-storage), but since we also rely on an ES5 environment due to dependencies from abstract-leveldown, in practice you will need the following shims in order to work correctly on all browsers (e.g. IE 8/9):
* [typedarray](https://github.com/substack/typedarray) for binary storage
* [es5-shim](https://github.com/es-shims/es5-shim) for just about everything
## Example

@@ -27,0 +34,0 @@

@@ -6,5 +6,3 @@ 'use strict';

var testCommon = require('./testCommon');
var testBuffer = new Buffer(new Uint8Array('hello'.split('').map(function (c) {
return c.charCodeAt(0);
})));
var testBuffer = new Buffer('hello');

@@ -30,43 +28,1 @@ require('abstract-leveldown/abstract/leveldown-test').args(localstorage, tape);

// we need typed arrays
function TypedArray(arg1) {
var result;
if (typeof arg1 === "number") {
result = new Array(arg1);
for (var i = 0; i < arg1; ++i) {
result[i] = 0;
}
} else {
result = arg1.slice(0);
result.buffer = result;
result.byteLength = result.length;
result.subarray = function (start, end) {
return result.slice(start, end);
};
result.set = function (array, offset) {
if (arguments.length < 2) {
offset = 0;
}
for (var i = 0, n = array.length; i < n; ++i, ++offset) {
result[offset] = array[i] & 0xFF;
}
};
}
if (typeof arg1 === "object" && arg1.buffer) {
result.buffer = arg1.buffer;
}
return result;
}
if (!window.Uint8Array) {
window.Uint8Array = TypedArray;
window.Uint32Array = TypedArray;
window.Int32Array = TypedArray;
}

Sorry, the diff of this file is not supported yet

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