Skip to content

Commit

Permalink
Made diff records immutable
Browse files Browse the repository at this point in the history
Also, updated package.json for devDependencies.
  • Loading branch information
Phillip Clark committed Nov 17, 2012
1 parent 6bf7854 commit d28420f
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 41 deletions.
6 changes: 4 additions & 2 deletions Readme.md
Expand Up @@ -127,9 +127,11 @@ observableDiff(lhs, rhs, function (d) {
```

## API Documentation
A startard import of `var diff = require('diff')` is assumed in all of the code examples. The import results in an object having the following publid properties:
A standard import of `var diff = require('diff')` is assumed in all of the code examples. The import results in an object having the following public properties:

* `diff` - a function that calculates the differences between two objects.
* `observableDiff` - a function that calculates the differences between two objects and reports each to an observer function.
* `applyDiff` - a function that applies any structural differences from one object to another.
* `applyChange` - applies a single change record to an origin object.
* `applyChange` - a function that applies a single change record to an origin object.


71 changes: 45 additions & 26 deletions lib/diff.js
Expand Up @@ -3,6 +3,41 @@
: function(F) { F(require,exports,module); } }). // Node.js
define(function (require, exports, module) {
"use strict";

var util = require('util');

function Diff(kind, path) {
Object.defineProperty(this, 'kind', { value: kind, enumerable: true });
if (path && path.length) {
Object.defineProperty(this, 'path', { value: path, enumerable: true });
}
}
function DiffEdit(path, origin, value) {
DiffEdit.super_.call(this, 'E', path);

Object.defineProperty(this, 'lhs', { value: origin, enumerable: true });
Object.defineProperty(this, 'rhs', { value: value, enumerable: true });
}
util.inherits(DiffEdit, Diff);
function DiffNew(path, value) {
DiffNew.super_.call(this, 'N', path);

Object.defineProperty(this, 'rhs', { value: value, enumerable: true });
}
util.inherits(DiffNew, Diff);
function DiffDeleted(path, value) {
DiffDeleted.super_.call(this, 'D', path);

Object.defineProperty(this, 'lhs', { value: value, enumerable: true });
}
util.inherits(DiffDeleted, Diff);
function DiffArray(path, index, item) {
DiffArray.super_.call(this, 'A', path);

Object.defineProperty(this, 'index', { value: index, enumerable: true });
Object.defineProperty(this, 'item', { value: item, enumerable: true });
}
util.inherits(DiffArray, Diff);

function arrayRemove(arr, from, to) {
var rest = arr.slice((to || from) + 1 || arr.length);
Expand All @@ -21,48 +56,29 @@
var rtype = typeof rhs;
if (ltype === 'undefined') {
if (rtype !== 'undefined') {
changes({kind: 'N', path: currentPath, rhs: rhs });
changes(new DiffNew(currentPath, rhs ));
}
} else if (rtype === 'undefined') {
changes({kind: 'D', path: currentPath, lhs: lhs});
changes(new DiffDeleted(currentPath, lhs));
} else if (ltype !== rtype) {
changes({kind: 'E', path: currentPath, lhs: lhs, rhs: rhs});
changes(new DiffEdit(currentPath, lhs, rhs));
} else if (ltype === 'object') {
stack = stack || [];
if (stack.indexOf(lhs) < 0) {
stack.push(lhs);
if (Array.isArray(lhs)) {
var i, ea = function(d) {
changes({
kind: 'A',
path: currentPath,
index: i,
item: d
});
changes(new DiffArray(currentPath, i, d));
};
for(i = 0; i < lhs.length; i++) {
if (i >= rhs.length) {
changes({
kind: 'A',
path: currentPath,
index: i,
item: {
kind: 'D',
lhs: lhs[i] }
});
changes(new DiffArray(currentPath, i, new DiffDeleted(undefined, lhs[i])));
} else {
deepDiff(lhs[i], rhs[i], ea, [], null, stack);
}
}
while(i < rhs.length) {
changes({
kind: 'A',
path: currentPath,
index: i,
item: {
kind: 'N',
rhs: rhs[i++] }
});
changes(new DiffArray(currentPath, i, new DiffNew(undefined, rhs[i++])));
}
} else {
var akeys = Object.keys(lhs);
Expand All @@ -83,7 +99,7 @@
stack.length = stack.length - 1;
}
} else if (lhs !== rhs) {
changes({kind: 'E', path: currentPath, lhs: lhs, rhs: rhs});
changes(new DiffEdit(currentPath, lhs, rhs));
}
}

Expand Down Expand Up @@ -143,6 +159,9 @@
}

function applyChange(target, source, change) {
if (!(change instanceof Diff)) {
throw new TypeError('[Object] change must be instanceof Diff');
}
if (target && source && change) {
var it = target, i, u;
u = change.path.length - 1;
Expand Down
32 changes: 19 additions & 13 deletions package.json
Expand Up @@ -19,19 +19,25 @@
"test": "./test"
},
"devDependencies" : {
"should": {
"version": "1.2.0"
},
"vows": {
"version": "0.6.4",
"dependencies": {
"eyes": {
"version": "0.1.8"
},
"diff": {
"version": "1.0.4"
}
}
"lodash": {
"version": "0.9.2"
},
"extend": {
"version": "1.1.1"
},
"should": {
"version": "1.2.1"
},
"vows": {
"version": "0.6.4",
"dependencies": {
"eyes": {
"version": "0.1.8"
},
"diff": {
"version": "1.0.4"
}
}
}
},
"scripts": {
Expand Down

0 comments on commit d28420f

Please sign in to comment.