![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
canop
Transport-agnostic operation-rich intention-preserving client-server JSON synchronization protocol.
Work in progress. Status: alpha. Currently only supports string values.
A simple client-server example is available, using adapters for WebSocket and CodeMirror.
Exploratory API description:
var canop = require('canop');
var server = new canop.Server({ data: {some: 'data'} });
// send must throw if it cannot send the message.
var client = new canop.Client({ send: function(message) {} });
server.addClient({
send: function(message) { client.receive(message); },
onReceive: function(receive) { client.send = receive; },
});
// You must emit syncing when the connection opens,
// and unsyncable when it closes.
client.emit('syncing');
client.once('ready', function() {…});
client.get(['some']); // 'data'
client.add(['some'], 0, 'modified '); // 'modified data'
client.move([], 'some', ['final']); // {final: 'modified data'}
client.on('signal', function(event) { event.clientId, event.data });
// Typically, sel is a list of selection ranges, where the first offset is the
// cursor (which moves the selection with shift+arrow).
// Also, connected is signaled when a node joins or leaves.
client.signal({connectred: true, name: 'Grace', focus: ['some'], sel: [[9,9]]});
client.clientCount // Number of clients currently connected.
client.signalFromClient[clientId] // aggregate of a client’s signals
// This event has the following keys:
// - changes: Array of [path, action type, parameters…]
// - posChanges: Array of canop.PosChange
var changeListener = function(event) {};
// Changes from other computers.
client.on('change', changeListener);
server.on('change', changeListener);
// Changes from this computer.
client.on('localChange', changeListener);
// An immutable copy of the data at a path. TODO
client.on('update', function(updated) {}, {path: ['some']});
client.on('localUpdate', function(updated) {}, {path: ['some']});
client.removeListener('change', changeListener);
// Returns an array of [path, action type, parameters…]
client.undo()
client.redo()
// When all local operations are acknowledged by the server.
client.on('synced', function() {});
// When some local operations are not acknowledged by the server.
client.on('syncing', function() {});
// When we cannot send operations to the server.
client.on('unsyncable', function() {});
// Return a position (eg. the index of a cursor in a string) corresponding to an
// initial position, mapped through a sequence of changes. You can get an
// Array of PosChanges from the 'change' event.
// By default, returns undefined if it cannot give an intention-preserving
// result. If bestGuess is true, returns a guess instead.
canop.changePosition(position, posChanges, bestGuess);
// Create custom operations. TODO
var actionType = client.registerAction(
canop.type.list | canop.type.string, // Types this applies to.
// Put whatever parameters here, modify object.
function action(object, params) {},
// Return the reverse operation for a change with this action.
// It must be so reverse(reverse(change)) == change.
function reverse(change) {});
client.act([actionType, path, …params]);
// For instance, this works:
client.act([client.action.set, ['final'], 'the end.']);
// You can buffer operations locally to make them into an atomic transaction.
client.actAtomically([
[client.action.stringAdd, ['some'], 0, 'modified'],
[client.action.objectMove, [], 'some', ['final']],
]);
Out of the box, Canop does not support peer-to-peer editing. If the probability of a central server crashing is at odds with your availability requirements, that is not a worry, as you can easily add a server fallback mechanism. On the other hand, if the frequency of edits goes beyond what a single server can handle, the algorithm can be tweaked to be peer-to-peer (at the expense of intention preservation). A description of that algorithm will be available in the paper. You may contribute a patch that implements this algorithm.
Atomic transactions will usually keep their meaning thanks
to Canop's intention preservation system. However, it is not guaranteed. For
instance, assuming we store the money of two bank accounts in a list. We encode
a transaction between them with two operations, add and remove: [20, 50]
① →
[15, 50]
② → [15, 55]
. We encode a swap between then with two operations
that set their values: [20, 50]
③ → [20, 20]
④ → [50, 20]
. If those
compound operations happen concurrently, they can converge to the following
sequence: [20, 50]
① → [15, 50]
③ → [15, 20]
② → [15, 25]
④ → [50, 25]
. Semantically, it should converge to [55, 15]
, which is clearly not the
case; one account did not receive its money, and the other received money that
was not even in the system.
Use client.actAtomically()
to send operations that are part of an atomic
transaction in bulk, ensuring that no operation will be executed in the middle, and
that the data will never be read within operations.
Alternatively, you may add a custom atomic operation (once the primitives for
that are implemented).
git clone https://github.com/espadrine/canop.git
cd canop
make
FAQs
Convergent algorithm for collaborative text.
The npm package canop receives a total of 5 weekly downloads. As such, canop popularity was classified as not popular.
We found that canop demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.