Overview
Traditional most applications are build with a datamodel suitable for single user access, all data update algorithms and storge policies are build with the mindset of one application manipulating the data.

In this scenario the app is responsible for ensuring data integrity and validity, and it usually does so by guiding the user with allowed or forbidden interactions. This works well as user input comes in syncronously, one action after annother, and hence the application can ensure that only valid actions can occure based on current state of the data.
Now assume you want to enable the given application for direct, realtime collaborative editing. The first thing that comes to mind is to simply forward all user inputs from one application to the other.

However, it becomes imediately clear that the principle of syncronous input is not valid anymore: there are noew multiple input sources for the application. Even worse, the remote input source is delayed and the user actions can arrive unordered. This means that the external inputs may not fit the current application state, and hence need to be rejected. This information must of course be provided back to the source, but this takes time again, and it could easily be that the source applicaton is already way ahead of the rejected action. This approach is clearly flawed, and it is almost impossible to keep the applicaion states syncronized this way.
It becomes clear that there must be a central entity which defines the current state for all applications, some kind of system that every update is written to and where each application can inquery the currently valid data. Using a database for that comes to mind. It does provide a consistent view on data and allows to be accessed from multiple applications worldwide. Pefect, rigth? Not really. Imagine the following sequence of events:

This would result in both applications think the sate is different. Of course the applications can read the state again to make sure they have it rigth, but it still would not have any guarantee that the state is still valid when the query finished. But when a application cannot be sure what the current state is, how can it write a new one, as the update may not be allowed?
Note
Databases do not provide any way of informing about updates. So you need to inform the other aplications about your changes manually, which provides almost the same challenge of synchronisation and ordering as the state manipulation itself
We can conclude that some verification logic is needed next to the database, that makes sure only valid writes occure and makes updates fail if invalid.
Datastructure Markup Language
OCP provides a custom markup language to create such datastructures and logic. They main building blocks you use are:
Documents: A document is the container for all your custom types and logic, it contains all you need for collaboration. For each application state a instance of a document is created.
Data objects: Objects are the main building block for a hirarchical data structure withi the document. There are predefined ones like Map and List, and from those you build your own objects by combining and cutomizing them.
Properties: Each provided object has properties that define its behaviour. You can also add your own, eihter for cutomisation of your code or for data storage
Functions: You code custom functions within your objects, which are callable from other objects and directly from your application
Events: Each provided object has a set of predefined events, like “onNewEntry” for a map, and you can even define your own events. You can define code within the objects that will be executed on event emitting, or listen for the events in your application
See for example the following data structure:

This document provides you with a vector that holds custom maps. You can add more of those custom maps by calling MyMainObject.AppendNew(), remove entries, access them for manipulation etc.. Each entry in this vector is a Map object, in our case with string keys and integer values. Of course they could be other types, and the values coulb even be annother custom object, further building your hirarchy. With this you are extremely flexible building a data layout to your needs.
Now to the logic: The main object has a function which is called when event onNewEntry is emitted, which happens always when a new entry is added to the vector. The function C is than called, and could check if it is ok to create a new entry based on all available data. If yes, it just returns doing nothing, if not it can raise an error and the whole update fails. See here for comparison the timelines for a successfull and a failing update of the shown document:

You can setup this exact document with a the following DML code:
Vector {
.name: "MyMainObject"
property string A: "Hello"
property string B: "World"
function C() {
//my Javascript code
}
.onNewEntry: function() {
MyMainObject.C()
}
.type: Map {
.name: "MyVectorEntry"
property int E: 1
property var F: 2
.key: string
.value: int
}
}
With this hirarchy setup you now can easily access your datastructure from outside, simply like this:
MyMainObject.C //call function
MyMainObject.1.E //read property E of first entry in vector
MyMainObject.0.Second //read map entry "Second" of the first map in the vector
Peer to Peer setup
OCP as an open source project has two main driving principles that guide our setup:
No cost of service: Whenever possible build the service in a way that does not generate hosting cost so that no fees need to be charged
Long term availability: Make sure the service works independend of any companies success or failure, so that there is no risk of shutting down for apps using the service
With those things in mind OCP decided to work on a peer-to-peer basis. There are no servers involved, no central entities required. Every user sets up a OCP node on his machine, which enables him to connect to other nodes and work on shared documents.

The OCP nodes are responsible for transfering data to each other as well as perfectly synchronizing the user documents at all time. Your applciation connects to the node via WAMP (websocket) and can use it as if would be a single source of truth.
The OCP node is a executable with a command line interface, written in Go. You simply configure and start it with the cli. Wamp libraries are available for basically all programming languages, so that you can easily connect and interact with the node from your application.


