There are plenty of software libraries out there that help sync data in real-time between users. But what happens when you want to give your users the ability to edit the same document simultaneously? They end up overwriting each other's data. So you end up either locking the document or abandoning the idea altogether.
To build real-time collaboration that your users will love, users need to know when and where their collaborators are working. So applications need to not just handle editing conflicts, but proactively prevent them! Convergence is the only solution that offers everything you need to build world-class real-time collaborative applications in days, not months.
Convergence combines an on-premise server and database with a JavaScript API to provide all the necessary functionality your app needs to provide a superlative real-time collaboration experience.
Convergence.connectAnonymously(domainUrl).then(domain => {
const modelService = domain.models();
modelService.openModel("people", "fred").then(model => {
// the model is {firstName: “Fred”, lastName: “Flanders”}
// A real time string
const firstName = model.elementAt("firstName");
firstName.on("set", evt => {
console.log(firstName.value());
});
firstName.on("insert", evt => {
console.log(firstName.value());
});
firstName.on("remove", evt => {
console.log(firstName.value());
});
// Listen to course grained events
firstName.on("model_changed", evt => {
console.log("change");
});
// Set the string
firstName.set("Ted"); // "Ted", "change"
// Delete the "T" at index 1
firstName.remove(0, 1); // "ed", "change"
// Insert an "N" at index 0.
firstName.insert("N", 0); // "Ned", "change"
});
});
domain.models().open(“collection”, model).then( model => {
const rtString = model.elementAt(“myString”);
// Create and publish a local cursor.
const localCursor = rtString.indexReference("cursor");
localCursor.set(3);
localCursor.publish(); // Listen for remote references.
rtString.on("reference", refEvent => {
const reference = refEvent.reference;
reference.on("set", e => {
console.log(“remote cursor set”, e.value);
});
reference.on("cleared", e => {
console.log(“remote cursor cleared”);
});
reference.on("disposed", e => {
console.log(“no more cursor”);
});
});
});
// Join a chat room by Id.
const room = domain.chat().joinRoom('my-chat-room').then(room => {
// Receive Messages
room.on("message", event => {
console.log(new Date(event.timestamp) +
" " + event.username +
": " + event.message);
});
// Send Messages
room.send("Hello Chat Room");
// Leave the room
room.leave();
});
Convergence.connectAnonymously(domainUrl).then(domain => {
const modelService = domain.models();
modelService.openModel("people", "fred").then(model => {
// the model is {firstName: “Fred”, lastName: “Flanders”}
// A real time string
const firstName = model.elementAt("firstName");
firstName.on("set", evt => {
console.log(firstName.value());
});
firstName.on("insert", evt => {
console.log(firstName.value());
});
firstName.on("remove", evt => {
console.log(firstName.value());
});
// Listen to course grained events
firstName.on("model_changed", evt => {
console.log("change");
});
// Set the string
firstName.set("Ted"); // "Ted", "change"
// Delete the "T" at index 1
firstName.remove(0, 1); // "ed", "change"
// Insert an "N" at index 0.
firstName.insert("N", 0); // "Ned", "change"
});
});
domain.models().open(“collection”, model).then( model => {
const rtString = model.elementAt(“myString”);
// Create and publish a local cursor.
const localCursor = rtString.indexReference("cursor");
localCursor.set(3);
localCursor.publish(); // Listen for remote references.
rtString.on("reference", refEvent => {
const reference = refEvent.reference;
reference.on("set", e => {
console.log(“remote cursor set”, e.value);
});
reference.on("cleared", e => {
console.log(“remote cursor cleared”);
});
reference.on("disposed", e => {
console.log(“no more cursor”);
});
});
});
Check out these resources to get a taste of the power Convergence provides.