NOTE: Demo has a somewhat broken UI in Firefox, please use Chrome!
This big and rather confusing screen is designed to show you how SyncIt works, it is broken up into many different areas!
On the top row in the middle there is a ReferenceServer which is running on simulated AJAX calls (through Sinon.JS), the Server is the single point of truth for SyncIt.
Either side of the Server view and the next three rows the screen can be thought of as being in two halves, each is a simulation of a seperate client and can be used to test out different scenarios for synchronization. In the top row beside the Server view are two tabbed areas for executing different API calls, note the "?" icon at the top right of them, it will explain in more detail what every tab does.
The row beneath the Server is the data which is available to each client through the SyncIt API. It is probably the data that you will use to draw the screen for the client.
Next up the screen becomes split into four, but it is really split into two halves, with each half split into two. There is a Queue and a Store, the Queue is information that still needs to be sent to the Server, while the Store should be data which is confirmed to be on the Server. The Server and the client are not tightly coupled however and you need to tell it that a particular update has been sent to the server using the Advance function. Do try and do silly things however, I think I have designed it to be pretty robust!
The rest of the screen is made up of log output. The first being a log which is tied to the individual client and the second is a log of requests recieved by the Server.
For more information on SyncIt and the reasons for it's existance please see the README.md on GitHub.
Downloading updates from the server is out-of-scope for SyncIt but once you have downloaded the updates from the server you can use the SyncIt.feed() method to put them into SyncIt.
Example code for doing this is:
var syncIt = new SyncIt(...);
syncIt.feed(
[{queueitem},{queueitem}],
function(dataset ,datakey ,jrec ,localQueueItems, serverQueueItems ,resolved) {
// This function will be called when there is a new
// version of the dataset/datakey on the server as well
// as in the local Queue. The server version will
// __always__ overwrite the local one, but you can call
// resolved with your own updates to advance local changes
// aftewards.
resolved(true,[{myNewQueueitem},{myNewQueueitem}]);
},
function(err,outstandingQueueitems) {
// If you did not resolve changes are there was some
// other error feeding data err will not by
// SyncIt_Constant.Error.OK and the queueitem which
// still need to be advanced locally we be in
// outstandingQueueitems
}
);
If all Queueitem have been dowloaded from the server, fed into SyncIt.feed() and the last callback has been called with an OK Errorcode then all changes that are on the server have been advanced locally.
The "get Dataset names" button will reveal another form that will enable you to download updates for different Datasets from the Server.
The "downloading it and feed them into SyncIt" button in the second form will download the updates from the simulated ReferenceServer and perform a SyncIt.feed() operation.
SyncIt, by design, has no method to upload data to the Server, that is code you need to write, but it will give you the very first Queueitem in the Queue if you use the SyncIt.getFirst() function. If the Server accepts the Queueitem it should be Advanced to the local Store (see the Advance tab), at which point it cannot be changed. When SyncIt.getFirst() passes the ErrorCode NO_DATA_FOUND all data has been uploaded. An example of the API call can be seen below...
jamesSyncIt.getFirst(function(err,queueitem) {
if (err === SyncIt_Constant.Error.NO_DATA_FOUND) {
// Nothing to upload
return;
}
if (err !== SyncIt_Constant.Error.OK) {
// throw?
}
xhr(
'http://server/' + queueitem.s + '/' + queueitem.k,
{
method: 'PATCH',
data: JSON.stringify(first),
...
}
).then(
function() {
// data now stored on server
jamesSyncIt.advance(function(err) {
...
});
},
function(err) {
// something went wrong... throw err?
}
);
});
The "to the server" button will call the SyncIt.getFirst() method and do a simulated AJAX call to the ReferenceServer, you can see the result of this in the "Simulated AJAX Request Log" in the "Server Log" tab at the top of the page.
If the request was successfully added to the Server you should proceed to the Advance tab.
The SyncIt.advance() function will find the first Queueitem and Advance it replacing what is in the Store. Once this is done it will remove the Queueitem
jamesSyncIt.getFirst(function(err,queueitem) {
if (err !== SyncIt_Constant.Error.OK) {
// throw?
}
xhr(
'http://server/' + queueitem.s + '/' + queueitem.k,
{
method: 'PATCH',
data: JSON.stringify(first),
...
}
).then(
function() {
// data now stored on server
jamesSyncIt.advance(function(err) {
...
});
},
function(err) {
// something went wrong... throw err?
}
);
});
This tab will do nothing except advance the first Queueitem. If you have not uploaded that Queueitem before advance it, the Queueitem will be effectively unretrievable.
A set operation is a request to completely replace the data at a Dataset / Datakey with new data, once Advanced none of the old data will survive, at least locally.
jamesSyncIt.set(
'cars',
'Subaru',
{ color: 'blue' }
function(err) { if (err === SyncIt_Constant.Error.OK) { success(); } }
);
This tab will perform a `set` operation. Please make sure that you fill in a valid Dataset and Datakey and use well formed JSON (which is more restrictive than JavaScript objects).
SyncIt.update() is different from SyncIt.set() in that it does not overwrite all data stored at that Dataset / Datakey but is able to selectively update any number of fields or subfields. This type of operation is very useful if your user interface can change specific data fields instead of whole records which might make conflict resolution much simpler (a "like" button would be super easy to implement).
jamesSyncIt.update(
'cars',
'Subaru',
{ $set: { pluspoints: ['has 4WD'] }, $inc { votes: 1 } },
function(err) { if (err === SyncIt_Constant.Error.OK) { success(); } }
);
This tab will perform an `update` operation. Please make sure that you fill in a valid Dataset and Datakey and use well formed JSON (which is more restrictive than JavaScript objects).
This operation enables removal of data stored at a Dataset / Datakey although the data is really only ever marked as deleted.
jamesSyncIt.remove(
'cars',
'Subaru',
function(err) { if (err === SyncIt_Constant.Error.OK) { success(); } }
);
This tab will perform a remove operation. Please make sure that you fill in a valid Dataset and Datakey.