diff --git a/README.md b/README.md index 26613a4..f55bc34 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,8 @@ When your application has changed the state of this object, the `sync` method of The [diffsync-todos app](https://github.com/janmonschke/diffsync-todos) provides an example client-side integration of diffsync into a todo list application. Check it out to find out how to integrate it into your existing application. In a nutshell, it makes use of `Object.observe` (and a polyfill for it) to track changes from within the app that are then synced to the server. +As a third optional parameter you can pass an options object to the constructor, that will then be applied to the internal diff-library. For a list of options, please check . + ### Server Setting up the server in a very minimal way (with express): @@ -130,6 +132,8 @@ Setting up the server in a very minimal way (with express): This is all that is needed for running the server part. There is no further addition necessary. Most of the logic is happening in the `DataAdapter`, which is described in the next section. +As a third optional parameter you can pass an options object to the constructor, that will then be applied to the internal diff-library. For a list of options, please check . + ### DataAdapter A `DataAdapter` is used by the server component internally to fetch data to initialize the synchronization and to save the data periodically. The simple interface allows to write a custom data provider for which ever data source you are using in your web app. diff --git a/src/client.js b/src/client.js index 90e0c98..e01bf43 100644 --- a/src/client.js +++ b/src/client.js @@ -1,17 +1,17 @@ -var isEmpty = require('lodash.isempty'), +var assign = require('lodash.assign'), bind = require('lodash.bind'), + isEmpty = require('lodash.isempty'), EventEmitter = require('events').EventEmitter, - jsondiffpatch = require('jsondiffpatch').create({ - objectHash: function(obj) { return obj.id || obj._id || JSON.stringify(obj); } - }), + jsondiffpatch = require('jsondiffpatch'), COMMANDS = require('./commands'), utils = require('./utils'), Client; -Client = function(socket, room){ +Client = function(socket, room, diffOptions){ if(!socket){ throw new Error('No socket specified'); } if(!room){ room = ''; } + if(!diffOptions){ diffOptions = {}; } this.socket = socket; this.room = room; @@ -26,6 +26,15 @@ Client = function(socket, room){ edits: [] }; + // set up the jsondiffpatch options + // see here for options: https://github.com/benjamine/jsondiffpatch#options + diffOptions = assign({ + objectHash: function(obj) { return obj.id || obj._id || JSON.stringify(obj); } + }, diffOptions); + + this.jsondiffpatch = jsondiffpatch.create(diffOptions); + + // let client be an EventEmitter EventEmitter.call(this); // bind functions @@ -154,7 +163,7 @@ Client.prototype.syncWithServer = function(){ * @return {Diff} The diff of both documents */ Client.prototype.createDiff = function(docA, docB){ - return jsondiffpatch.diff(docA, docB); + return this.jsondiffpatch.diff(docA, docB); }; /** @@ -164,7 +173,7 @@ Client.prototype.createDiff = function(docA, docB){ * @param {Diff} patch */ Client.prototype.applyPatchTo = function(obj, patch){ - jsondiffpatch.patch(obj, patch); + this.jsondiffpatch.patch(obj, patch); }; /** diff --git a/src/server.js b/src/server.js index 3a0b05f..822f4c2 100644 --- a/src/server.js +++ b/src/server.js @@ -1,15 +1,15 @@ -var isEmpty = require('lodash.isempty'), +var assign = require('lodash.assign'), bind = require('lodash.bind'), - jsondiffpatch = require('jsondiffpatch').create({ - objectHash: function(obj) { return obj.id || obj._id || JSON.stringify(obj); } - }), + isEmpty = require('lodash.isempty'), + jsondiffpatch = require('jsondiffpatch'), COMMANDS = require('./commands'), utils = require('./utils'), Server; -Server = function(adapter, transport){ +Server = function(adapter, transport, diffOptions){ if(!(adapter && transport)){ throw new Error('Need to specify an adapter and a transport'); } + if(!diffOptions){ diffOptions = {}; } this.adapter = adapter; this.transport = transport; @@ -18,6 +18,14 @@ Server = function(adapter, transport){ // bind functions this.trackConnection = bind(this.trackConnection, this); + // set up the jsondiffpatch options + // see here for options: https://github.com/benjamine/jsondiffpatch#options + diffOptions = assign({ + objectHash: function(obj) { return obj.id || obj._id || JSON.stringify(obj); } + }, diffOptions); + + this.jsondiffpatch = jsondiffpatch.create(diffOptions); + this.transport.on('connection', this.trackConnection); }; @@ -124,12 +132,12 @@ Server.prototype.receiveEdit = function(connection, editMessage, sendToClient){ // 3) patch the shadow // var snapshot = utils.deepCopy(clientDoc.shadow.doc); - jsondiffpatch.patch(clientDoc.shadow.doc, utils.deepCopy(edit.diff)); + this.jsondiffpatch.patch(clientDoc.shadow.doc, utils.deepCopy(edit.diff)); // clientDoc.shadow.doc = snapshot; // apply the patch to the server's document // snapshot = utils.deepCopy(doc.serverCopy); - jsondiffpatch.patch(doc.serverCopy, utils.deepCopy(edit.diff)); + this.jsondiffpatch.patch(doc.serverCopy, utils.deepCopy(edit.diff)); // doc.serverCopy = snapshot; // 3.a) increase the version number for the shadow if diff not empty @@ -142,7 +150,7 @@ Server.prototype.receiveEdit = function(connection, editMessage, sendToClient){ console.log('error', 'patch rejected!!', edit.serverVersion, '->', clientDoc.shadow.serverVersion, ':', edit.localVersion, '->', clientDoc.shadow.localVersion); } - }); + }.bind(this)); // 4) save a snapshot of the document this.saveSnapshot(editMessage.room); @@ -166,9 +174,7 @@ Server.prototype.saveSnapshot = function(room){ Server.prototype.sendServerChanges = function(doc, clientDoc, send){ // create a diff from the current server version to the client's shadow - // important: use deepcopied versions - // var diff = jsondiffpatch.diff(utils.deepCopy(clientDoc.shadow.doc), utils.deepCopy(doc.serverCopy)); - var diff = jsondiffpatch.diff(clientDoc.shadow.doc, doc.serverCopy); + var diff = this.jsondiffpatch.diff(clientDoc.shadow.doc, doc.serverCopy); var basedOnServerVersion = clientDoc.shadow.serverVersion; // add the difference to the server's edit stack @@ -182,7 +188,7 @@ Server.prototype.sendServerChanges = function(doc, clientDoc, send){ clientDoc.shadow.serverVersion++; // apply the patch to the server shadow - jsondiffpatch.patch(clientDoc.shadow.doc, utils.deepCopy(diff)); + this.jsondiffpatch.patch(clientDoc.shadow.doc, utils.deepCopy(diff)); } // we explicitly want empty diffs to get sent as well diff --git a/test/client_test.js b/test/client_test.js index e75978c..230abed 100644 --- a/test/client_test.js +++ b/test/client_test.js @@ -37,6 +37,12 @@ describe('DiffSync Client', function(){ assert.notStrictEqual(testClient().room, null); assert.notStrictEqual(testClient().room, undefined); }); + + it('should apply the correct options to jsondiffpatch', function(){ + var client = new Client({}, 1, { textDiff: { minLength: 2 }}); + + assert(client.jsondiffpatch.options().textDiff.minLength === 2); + }); }); describe('initialize', function(){ diff --git a/test/server_test.js b/test/server_test.js index 6b773fa..39a386e 100644 --- a/test/server_test.js +++ b/test/server_test.js @@ -54,6 +54,12 @@ describe('DiffSync Server', function(){ new Server(testAdapter(), testTransport()); }); }); + + it('should apply the correct options to jsondiffpatch', function(){ + var client = new Server(testAdapter(), testTransport(), { textDiff: { minLength: 2 }}); + + assert(client.jsondiffpatch.options().textDiff.minLength === 2); + }); }); describe('trackConnection', function(){