Skip to content

Commit

Permalink
throws on incompatible type
Browse files Browse the repository at this point in the history
  • Loading branch information
bchr02 committed Sep 26, 2016
1 parent 8fc07bd commit ae5ede3
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 20 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,3 @@ function proceed(error, file) {

}
```

All operations happen asynchronously and operations are throttled to prevent a fs.writeFile race condition.
48 changes: 32 additions & 16 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ function Filejson(cfg) {

var self = this;

// Used to store a reference for our setTimeout function.
// The setTimeout function is used to throttle the saving to disk.
var task;
// Used to store a reference to our setImmediate scheduled timers so that we can cancel all in the queue execpt the last one.
var scheduledTimers;

// Prevents the oportunity for a race condition to occure in the scenario where one fs.writeFile operation tries to overlap another.
// This could be the result of slow IO or a large object being written.
Expand All @@ -29,15 +28,36 @@ function Filejson(cfg) {
return Reflect.get(target, key, receiver);
},
set: function(target, key, value, receiver) {

var check = function(value, tree) {
var t = typeof value;
if(!(t === 'string' || t === 'number' || t === 'object' || t === 'boolean' || t === 'undefined')) {
throw new Error("NON-JSON COMPATIBLE TYPE FOUND. " + t + " found within: " + tree);
}
};
var loopAll = function(obj, tree) {
for(var key in obj){
tree += "." + key;
if(typeof obj[key] !== 'object'){
check(obj[key], tree);
}
else {
loopAll(obj[key], tree);
}
}
};

if(!self.cfg.speed) {
loopAll(self.contents, "file.contents");
}

if(!self.cfg.filename) {
throw new Error("You must specify a filename");
}

if( value instanceof Object ) {
value = new Proxy(value, this);
}

// The default behavior to store the value
Reflect.set(target, key, value, receiver);

Expand All @@ -59,19 +79,16 @@ function Filejson(cfg) {
this.cfg = {
filename: cfg.filename || "",
space: cfg.space || 2,
delay: cfg.delay || 3000,
verbose: cfg.verbose || false
verbose: cfg.verbose || false,
speed: cfg.speed || false
};

// Boolean - pauses any future changes to this.contents from auto triggering a save to disk
this.paused;

// Boolean - if a race condition needed to be avoided then there will be pending writes
this.pendingWrites = false;

this.save = function(callback) {
clearTimeout(task);
task = setTimeout(function() {
clearImmediate(scheduledTimers);
scheduledTimers = setImmediate(function() {
var contents;
try {
contents = JSON.stringify(this.contents, null, this.cfg.space);
Expand All @@ -80,9 +97,8 @@ function Filejson(cfg) {
callback(err, this);
return;
}
if(!saving) {
if(!saving) { // prevents possible race condition
saving = true;
this.pendingWrites = false;
fs.writeFile(this.cfg.filename, contents, function(error) {
saving = false;
if(!error) {
Expand All @@ -92,9 +108,9 @@ function Filejson(cfg) {
}.bind(this));
}
else {
this.pendingWrites = true;
this.save(callback);
}
}.bind(this), this.cfg.delay);
}.bind(this));
};

/**
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "filejson",
"version": "1.0.5",
"version": "1.0.6",
"description": "Use a JSON encoded file to automatically save a JavaScript value to disk whenever that value changes.",
"main": "app.js",
"scripts": {
Expand All @@ -9,9 +9,13 @@
"author": "Bill Christo",
"license": "MIT",
"devDependencies": {
"eslint": "^3.5.0"
"eslint": "^3.6.0"
},
"dependencies": {},
"bugs": {
"url": "https://github.com/bchr02/filejson/issues"
},
"homepage": "https://github.com/bchr02/filejson#readme",
"keywords": [
"file",
"disk",
Expand Down

0 comments on commit ae5ede3

Please sign in to comment.