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

node-persist

Package Overview
Dependencies
Maintainers
3
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-persist - npm Package Compare versions

Comparing version 0.0.12 to 1.0.0

23

examples/counter/counter.js

@@ -18,11 +18,22 @@ /*

logging: true,
ttl: ttl,
dir: __dirname + '/store'
ttl: ttl
}).then(function() {
if(!storage.getItem('counter')) {
storage.setItemSync('counter', 0);
return storage.getItem('counter');
}).then(function(counter) {
if (! counter) {
return storage.setItemSync('counter', 0);
}
console.log("counter is: " + storage.getItem('counter'));
}, function(err) {
return counter
}).then(function() {
return storage.getItem('counter');
}).then(function(counter) {
console.log('counter is ' + counter);
}).catch(function(err) {
console.error(err);
throw err;
});

@@ -29,0 +40,0 @@

{
"name": "node-persist",
"version": "0.0.12",
"version": "1.0.0",
"description": "Super-easy (and fast) persistent data structures in Node.js, modeled after HTML5 localStorage",

@@ -5,0 +5,0 @@ "main": "./src/node-persist.js",

@@ -23,20 +23,34 @@ # node-persist

Async example
```js
//you must first call storage.init or storage.initSync
storage.initSync();
//you must first call storage.init
//you must first call storage.initSync
storage.init( /* options ... */ );
//then start using it
storage.setItem('name','yourname');
console.log(storage.getItem('name'));
storage.setItem('name','yourname')
.then(function() {
var batman = {
first: 'Bruce',
last: 'Wayne',
alias: 'Batman'
};
return storage.getItem('name')
})
.then(function(value) {
storage.setItem('batman',batman);
console.log(storage.getItem('batman').alias);
console.log(value); // yourname
})
```
Sync example
```
//you must first call storage.initSync
storage.initSync();
//then start using it
storage.setItemSync('name','yourname');
console.log(storage.getItemSync('name')); // yourname
```
## Run the examples:

@@ -50,2 +64,16 @@

## 1.0.0 change logs
Mostly non-backward changes
* `storage.getItem()` now returns a promise
* `storage.valuesWithKeyMatch()` no longer accepts a callback
* `storage.values()` no longer accepts a callback
* `storage.key()` is gone
* The default `dir` is now `process.cwd() + (dir || '.node-persist/storage')`, unless you use an absolute path
* added `storage.get()`, alias to `getItem()`
* added `storage.set()`, alias to `setItem()`
* added `storage.del()`, `storage.rm()`, as aliases to `removeItem()`
* Keys, on the file system are base64 encoded with the replacement of the `/`
## API Documentation

@@ -83,16 +111,20 @@

#### `getItem(key, [callback])` - returns value synchronous* but may linger async call if unless ttl expired,
This function will get a key from your database in memory, and return its value, or undefined if it is not present.
#### `getItem(key, [callback])` - returns promise,
This function will get a key from your database in memory
\* you can always use it in a asynchronous mode, meaning passing a callback (because we cannot return a Promise for this one) - the callback will be executed immediately and synchronously if there is no ttl used. If you are using ttl but you are also using `options.interval` or `options.continous=false` the deletion of the expired keys will wait for either the interval to kick in or if you manually `persist`
```js
```js
// callback
storage.getItem('name', function (err, value) {
// use value here after makign sure expired-ttl key deletion has occured, in that case value === undefined
}); // value is also returned
storage.getItem('obj').key1;
storage.getItem('arr')[42];
// use value here after making sure expired-ttl key deletion has occured, in that case value === undefined
});
// promise
storage.getItem('obj').then(function(value) {
})
```
#### `getItemSync(key)` - returns value
The only synchronous part is the deletion of an expired-ttl key, if `options.ttl` is used, otherwise it behaves just like `getItem`
All synchronous part along with the deletion of an expired-ttl key, if `options.ttl` is used

@@ -151,10 +183,6 @@ #### `setItem(key, value, [callback])` - asynchronous*, returns Promise

```
#### `values([callback])` - [DEPRECATED] synchronous, but still returns array
This function is synchronous, it does not need to accept a callback, so that signature is getting deprecated.
#### `values()` - returns array
```js
// notice this callback does not accept an error as a 1st argument, to support backward compatibility
// but will be removed on next minor release
storage.values(function(values) {
}));
var values = storage.values();
```

@@ -173,15 +201,7 @@

```
#### `valuesWithKeyMatch(match, [callback])` - [DEPRECATED] synchronous, but still returns array
This function is synchronous, it does not need to accept a callback, so that signature getting deprecated
#### `valuesWithKeyMatch(match)` - synchronous, returns array
```js
// notice this callback does not accept an error as a 1st argument, to support backward compatibility
// but will be removed on next minor release
storage.valuesWithKeyMatch('man', function(values) {
}));
var values = storage.valuesWithKeyMatch('man');
```
#### `key(n)` - [DEPRECATED] synchronous, returns string
This function returns a key with index n in the database, or null if it is not present. The ordering of keys is not known to the user. It is getting deprecated because `Object.keys()` does not guarantee the order of the keys, so this functionality is fragile.
#### `keys()` - synchronous, returns array

@@ -188,0 +208,0 @@

@@ -8,7 +8,8 @@ /*

path = require('path'),
mkdirp = require("mkdirp"),
mkdirp = require('mkdirp'),
Q = require('q'),
pkg = require('../package.json'),
defaults = {
dir: 'persist',
dir: '.' + pkg.name + '/storage',
stringify: JSON.stringify,

@@ -37,10 +38,31 @@ parse: JSON.parse,

/*
* To support backward compatible callbacks,
* i.e callback(data) vs callback(err, data);
* replace with noop and fix args order, when ready to break backward compatibily for the following API functions
* - values()
* - valuesWithKeyMatch()
* hint: look for 'todo-breaks-backward' in the source
*/
btoa = function (string) {
return new Buffer(string.toString(), 'binary').toString('base64');
},
atob = function (string) {
return new Buffer(string, 'base64').toString('binary');
},
sanitize = function (string) {
return btoa(string).replace(btoaPathSepRegExp, atobPathSepReplacement);
},
unsanitize = function (string) {
return atob(string.replace(atobPathSepReplacementRegExp, '/'));
},
btoaPathSepRegExp = new RegExp(path.sep, 'g'),
atobPathSepReplacement = '__SLASH__',
atobPathSepReplacementRegExp = new RegExp(atobPathSepReplacement, 'g'),
/*
* To support backward compatible callbacks,
* i.e callback(data) vs callback(err, data);
* replace with noop and fix args order, when ready to break backward compatibily for the following API functions
* - values()
* - valuesWithKeyMatch()
* hint: look for 'todo-breaks-backward' in the source
*/
noopWithoutError = function() {};

@@ -159,13 +181,2 @@

key: function (n) {
// todo-breaks-backward: remove this function
// this is fragile, keys are not guaranteed to be in a any order, so 2 calls using the same index could return a different result
// http://stackoverflow.com/a/5525820/493756, see the ECMAScript source in that answer
var keys = this.keys();
if (keys.length <= n) {
return null;
}
return keys[n];
},
keys: function () {

@@ -185,22 +196,10 @@ return Object.keys(this.data);

values: function(callback) {
// todo-breaks-backward: remove callback option
callback = isFunction(callback) ? callback : noopWithoutError;
var values = this.keys().map(function(k) {
values: function() {
return this.keys().map(function(k) {
return this.data[k];
}.bind(this));
// todo-breaks-backward: remove callback, no need, this is sync
callback(values);
return values;
},
valuesWithKeyMatch: function(match, callback) {
// todo-breaks-backward: remove callback option
callback = isFunction(callback) ? callback : noopWithoutError;
valuesWithKeyMatch: function(match) {
match = match || /.*/;

@@ -223,7 +222,9 @@

// todo-breaks-backward: remove callback, no need this is sync
callback(values);
return values;
},
set: function () {
return this.setItem(key, value, callback);
},
setItem: function (key, value, callback) {

@@ -286,4 +287,10 @@ callback = isFunction(callback) ? callback : noop;

get: function (key, callback) {
return this.getItem(key, callback);
},
getItem: function (key, callback) {
callback = isFunction(callback) ? callback : noop;
var deferred = Q.defer();
if (this.isExpired(key)) {

@@ -293,11 +300,12 @@ this.log(key + ' has expired');

callback(null, null);
return;
return deferred.resolve(null);
}
this.removeItem(key, function() {
callback(null, null);
return this.removeItem(key).then(function() {
return null;
});
} else {
callback(null, this.data[key]);
return this.data[key];
deferred.resolve(this.data[key]);
}
return deferred.promise;
},

@@ -313,2 +321,10 @@

del: function (key, callback) {
return this.removeItem(key, callback);
},
rm: function (key, callback) {
return this.removeItem(key, callback);
},
removeItem: function (key, callback) {

@@ -430,3 +446,4 @@ callback = isFunction(callback) ? callback : noop;

var file = path.join(options.dir, key);
var file = path.join(options.dir, sanitize(key));
var ttlFile;

@@ -461,3 +478,3 @@

if (options.ttl) {
ttlFile = path.join(options.ttlDir, key);
ttlFile = path.join(options.ttlDir, sanitize(key));
mkdirp(path.dirname(ttlFile), function(err) {

@@ -483,3 +500,3 @@ fs.writeFile(ttlFile, options.stringify(self.ttls[key]), options.encoding, function() {

var options = this.options;
var file = path.join(options.dir, key);
var file = path.join(options.dir, sanitize(key));
try {

@@ -496,3 +513,3 @@ mkdirp.sync(path.dirname(file));

if (options.ttl) {
ttlFile = path.join(options.ttlDir, key);
ttlFile = path.join(options.ttlDir, sanitize(key));
mkdirp.sync(path.dirname(ttlFile));

@@ -514,3 +531,3 @@ fs.writeFileSync(ttlFile, options.stringify(this.ttls[key]));

//check to see if key has been persisted
var file = path.join(options.dir, key);
var file = path.join(options.dir, sanitize(key));
fs.exists(file, function (exists) {

@@ -536,3 +553,3 @@ if (exists) {

if (options.ttl) {
var ttlFile = path.join(options.ttlDir, key);
var ttlFile = path.join(options.ttlDir, sanitize(key));
fs.exists(ttlFile, function (exists) {

@@ -609,3 +626,3 @@ if (exists) {

if (curr[0] !== '.') {
deferreds.push(parseFn(curr));
deferreds.push(parseFn(unsanitize(curr)));
}

@@ -653,3 +670,3 @@ }

var json = fs.readFileSync(path.join(dir, curr), this.options.encoding);
hash[curr] = this.parseString(json);
hash[unsanitize(curr)] = this.parseString(json);
}

@@ -683,3 +700,3 @@ }

var result;
var file = path.join(dir, key);
var file = path.join(dir, sanitize(key));
var options = this.options;

@@ -709,3 +726,3 @@

parseFileSync: function(key, dir, hash) {
var file = path.join(dir, key);
var file = path.join(dir, sanitize(key));
hash[key] = fs.readFileSync(file, this.options.encoding);

@@ -724,3 +741,3 @@ this.log("loaded: " + dir + "/" + key);

var file = path.join(options.dir, key);
var file = path.join(options.dir, sanitize(key));
if (fs.existsSync(file)) {

@@ -730,3 +747,3 @@ fs.unlinkSync(file);

if (options.ttl) {
var ttlFile = path.join(options.ttlDir, key);
var ttlFile = path.join(options.ttlDir, sanitize(key));
if (fs.existsSync(ttlFile)) {

@@ -740,7 +757,6 @@ fs.unlinkSync(ttlFile);

dir = path.normalize(dir);
if (dir !== path.resolve(dir)) {
dir = path.join(__dirname, "storage", dir || "");
this.log("Made dir absolute: " + dir);
if (path.isAbsolute(dir)) {
return dir;
}
return dir;
return path.join(process.cwd(), dir);
},

@@ -754,5 +770,8 @@

this.options && this.options.logging && console.log.apply(console, arguments);
}
},
sanitize: sanitize,
unsanitize: unsanitize
};
module.exports = LocalStorage;

@@ -121,9 +121,2 @@

it("should return a key() by index", function(done) {
storage.setItemSync("item2", items.item2);
assert.equal(storage.key(1), Object.keys(items)[1]);
storage.removeItemSync("item2");
done();
});
it("should return all keys()", function(done) {

@@ -192,6 +185,7 @@ assert.deepEqual(storage.keys(), ["item1"]);

it("should getItem() from cache", function(done) {
var value = storage.getItem("item1");
assert.equal(value, items.item1);
done();
it("should getItem().then() from cache", function(done) {
storage.getItem("item1").then(function(value) {
assert.equal(value, items.item1);
done();
})
});

@@ -283,20 +277,19 @@

storage.initSync({
storage.init({
dir: randDir(),
interval: 2000 // persist to disk every 2 seconds
});
}).then(function() {
var startTime = +new Date();
var startTime = +new Date();
storage.setItem("item999", 1).then(function() {
// 2 seconds later, that file should be there and that promise should resolve now.
var endTime = +new Date();
assert.approximately(endTime, startTime, 2500, "within 2.5s or so");
assert.equal(true, fs.existsSync(storage.options.dir + "/" + storage.sanitize("item999")));
done();
});
storage.setItem("item1", 1).then(function() {
// 2 seconds later, that file should be there and that promise should resolve now.
var endTime = +new Date();
assert.approximately(endTime, startTime, 2500, "within 2.5s or so");
assert.equal(true, fs.existsSync(storage.options.dir + "/item1"));
done();
// check if the item1 file exists immediately, it shouldnt
assert.notEqual(true, fs.existsSync(storage.options.dir + "/" + storage.sanitize("item999")));
});
// check if the item1 file exists immediately, it shouldnt
assert.notEqual(true, fs.existsSync(storage.options.dir + "/item1"));
});

@@ -303,0 +296,0 @@ });

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