0x6 Changesets & Operations & Actions

Design Philosophy

Changeset / operation / action are the basic data transmission layer concepts for real-time collaboration. They are implemented through revision-based version control for temporal control and conflict resolution. These concepts have been well-practiced in the 0.x version of Wugetable architecture. However, there has been no clear separation between the computation and storage layers.

The 1.x architecture, while retaining the basic concepts, implements data computation, data compensation, and data storage processes on the server-side. By properly dividing domains, logical layering and stable data interaction can be achieved. By moving performance hotspots to the server-side, the collaborative architecture can theoretically be independent of computational performance, allowing for optimization of performance hotspots in the future using various means.

Command & Operation & Transaction

Command & Operation & Transaction are a set of closely related concepts, linking user changes and storage logic to the database.

Command

In the frontend, we use Command to represent a user instruction. Common commands include setRecords and addRecords. Simply put, each time a user makes a change to the data via mouse or keyboard, it will be abstracted into a specific command for execution, modifying the underlying table data. That is to say, after a table data snapshot (snapshot) goes through a command, it becomes snapshot'. Stacking them up, it looks like this:

Cmd1(snapshot) = snapshot', Cmd2(snapshot') => snapshot''

Operation

Operation is a description of the data entity resulting from the execution of a command. One Command generates one Op. Let's look at the simplest op data structure:

{
    cmd: CommandName;
    actions: IAction[];
}

CommandName is the command name, and actions are a set of changes describing modifications to the snapshot. When actions are applied to the snapshot in sequence, the snapshot completes a modification and becomes snapshot'.

At the same time, each Op can be rolled back, which is the undo/redo functionality we provide to the user side. It can be seen that there is an implicit condition here: during the process of snapshot -> snapshot', no other changes are allowed to be introduced. So, in fact, the concept of "lock" is implicitly included in the apply process. However, since the frontend data changes are generated by UI interaction and executed by single-threaded JS, there is no possibility of concurrency, so there is no need to do anything.

Changeset

Changeset is a wrapper for Op operations. Based on Op, it encapsulates basic information such as revision + baseRevision (version number/base version number), resourceId, etc., ensuring that Op can be applied to the snapshot in sequence and providing temporal guarantees for Op's transform. Each message communication will be wrapped into a changeset for transmission. Ops generated between each network communication for each Resource are merged into a single Changeset for transmission.