New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

canop

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

canop - npm Package Compare versions

Comparing version 0.2.2 to 0.2.3

.canop.js.swn

97

canop.js

@@ -14,5 +14,6 @@ (function (root, factory) {

var actions = {
set: 0,
stringAdd: 7,
stringRemove: 8
pass: 0,
set: 1,
stringAdd: 8,
stringRemove: 9
};

@@ -59,4 +60,12 @@ var PROTOCOL_VERSION = 0;

},
// Is this operation's type rebaseable (ie, its indices get reshifted)?
// If it is, then key = index in a list.
rebaseable: function rebaseable() {
return this.action === actions.stringAdd ||
this.action === actions.stringRemove;
},
// Get this operation modified by a list of PosChanges.
getModifiedBy: function getModifiedBy(changes) {
if (!this.rebaseable()) { return; }
var oldEnd = this.key + this.value.length;

@@ -79,4 +88,3 @@ this.original = {

if (key === undefined || end === undefined) {
this.key = 0; // Nulled to avoid adding spaces at the end in toString().
this.value = ""; // Null operation.
this.action = actions.pass; // Nulled to avoid adding spaces at the end in toString().
} else {

@@ -97,8 +105,11 @@ this.key = key;

inverse: function inverse() {
var op = this.dup();
if (this.action === actions.stringAdd) {
var op = this.dup();
op.action = actions.stringRemove;
} else if (this.action === actions.stringRemove) {
var op = this.dup();
op.action = actions.stringAdd;
} else if (this.action === actions.set) {
var newValue = op.key;
op.key = op.value; // Old value
op.value = newValue;// New value
}

@@ -170,2 +181,6 @@ return op;

var change = changes[i];
if (change === undefined) {
if (bestGuess) { return key; }
else { return; }
}
var newKey = change.update(key, originalKey);

@@ -271,7 +286,4 @@ var contextFound = false;

var change = this.list[i].change();
if (change !== undefined) {
posChanges.push(change);
} else {
posChanges = [];
}
if (change === undefined) { return posChanges; }
posChanges.push(change);
}

@@ -284,8 +296,7 @@ return posChanges;

for (var i = this.list.length - 1; i >= 0; i--) {
var change = this.list[i].change().inverse();
if (change !== undefined) {
posChanges.push(change);
} else {
return posChanges;
}
var change = this.list[i].change();
if (change === undefined) { return posChanges; }
change = change.inverse();
if (change === undefined) { return posChanges; }
posChanges.push(change);
}

@@ -306,2 +317,8 @@ return posChanges;

},
// Change the whole value. Mutates this.
set: function setOp(path, newVal, oldVal, base, local) {
var aop = new AtomicOperation(actions.set, newVal, oldVal, base, local);
this.list.push(aop);
return aop;
},
// Assume we start with the empty value.

@@ -394,3 +411,3 @@ toString: function toString() {

this.base = params.base || 0; // Most recent known canon operation index.
this.localId = 0; // Identifier of the current machine.
this.id = 0; // Identifier of the current machine.
this.local = new Operation(); // Operation for local changes.

@@ -405,5 +422,3 @@ this.sent = new Operation(); // Operation for changes sent but not acknowledged.

// Note: servers should never disable data.
if (params.disableData !== undefined) {
this.disableData = params.disableData;
}
this.disableData = !!params.disableData;
this.data = undefined; // Holds the current data including local operations.

@@ -433,6 +448,6 @@ // Also, clients should never have params.data.

try {
if (self.localId === 0) {
if (self.id === 0) {
self.send(JSON.stringify([PROTOCOL_PLEASE, PROTOCOL_VERSION]));
} else {
self.send(JSON.stringify([PROTOCOL_SINCE, self.localId, self.base]));
self.send(JSON.stringify([PROTOCOL_SINCE, self.id, self.base]));
}

@@ -558,4 +573,6 @@ self.clientState = STATE_LOADING;

}
if (delta[1][0] === 0) { // set
} else if ((delta[1][0] === 7) || (delta[1][0] === 8)) {
if (delta[1][0] === actions.pass) { // pass
} else if (delta[1][0] === actions.set) { // set
} else if ((delta[1][0] === actions.stringAdd) ||
(delta[1][0] === actions.stringRemove)) {
// string add / remove

@@ -707,9 +724,9 @@ if (typeof delta[1][1] !== "number") { // offset

reset: function(data, base, localId) {
reset: function(data, base, id) {
this.local = new Operation();
this.sent = new Operation();
this.canon = new Operation();
this.localId = localId;
this.id = id;
if (!this.disableData) { this.data = data; }
this.receiveChange([PROTOCOL_DELTA, [], [[[base, localId, 0], [actions.set, data]]]]);
this.receiveChange([PROTOCOL_DELTA, [], [[[base, id, 0], [actions.set, data]]]]);
},

@@ -862,3 +879,6 @@ localToSent: function() {

var aops = []; // AtomicOperations
if (actionType === actions.stringAdd) {
if (actionType === actions.pass) {
} else if (actionType === actions.set) {
aops.push(this.set(action));
} else if (actionType === actions.stringAdd) {
aops.push(this.stringAdd(action));

@@ -876,3 +896,3 @@ } else if (actionType === actions.stringRemove) {

return this.local.add(action[1], action[2], action[3],
this.base, this.localId);
this.base, this.id);
},

@@ -883,4 +903,10 @@ // action: [actions.stringAdd, path, …params]

return this.local.remove(action[1], action[2], action[3],
this.base, this.localId);
this.base, this.id);
},
// action: [actions.set, path, new value, old value]
// Return an AtomicOperation.
set: function(action) {
return this.local.set(action[1], action[2], action[3],
this.base, this.localId);
},

@@ -893,3 +919,3 @@ // Send a signal to all other nodes of the network.

try {
this.send(JSON.stringify([PROTOCOL_SIGNAL, this.localId, content]));
this.send(JSON.stringify([PROTOCOL_SIGNAL, this.id, content]));
} catch(e) {

@@ -935,2 +961,3 @@ this.emit('unsyncable', e);

self.removeClient(newClient);
var oldClientId = newClient.id;
newClient.id = protocol[1];

@@ -950,2 +977,6 @@ newClient.base = base;

}
// The client may have had its id changed.
delete self.signalFromClient[oldClientId];
self.signalFromClient[newClient.id] = self.signalFromClient[newClient.id] ||
Object.create(null);
self.sendSignalsToClient(newClient);

@@ -952,0 +983,0 @@ } else if (messageType === PROTOCOL_DELTA) {

@@ -33,11 +33,9 @@ # Canop Protocol

- `action`: set = 0
- `action`: pass = 0, set = 1
- `key`: any JSON value, possibly of a different type.
- `value`: old value, if any.
(Note: `[0]` "set nothing to nothing" is the empty operation.)
Delta for objects:
- `action`: add = 1, remove = 2, move = 3.
- `action`: add = 2, remove = 3, move = 4.
- `key`: key (in the object) as a string.

@@ -48,3 +46,3 @@ - `value`: value (for move, path of the new location).

- `action`: add = 4, remove = 5, move = 6.
- `action`: add = 5, remove = 6, move = 7.
- `key`: index (in the list).

@@ -55,3 +53,3 @@ - `value`: value (for move, path of the new location).

- `action`: add = 7, remove = 8.
- `action`: add = 8, remove = 9.
- `key`: offset (in the string).

@@ -58,0 +56,0 @@ - `value`: string.

{
"name": "canop",
"version": "0.2.2",
"version": "0.2.3",
"description": "Convergent algorithm for collaborative text.",

@@ -5,0 +5,0 @@ "main": "canop.js",

@@ -146,8 +146,7 @@ `canop`

- Signal a list of all currently connected clients and of disconnections
- Separate wire and widget hooks.
- Textarea adapter
- Customizable UI sync debouncing
- JSON-compatible protocol
- Array index rebasing
- Autosave of operations to disk
- Separate display hooks from transport hooks
- Allow creating user-defined operations

@@ -128,6 +128,6 @@ var canop = require('../canop.js');

// localId
// id
var star = new Star('');
assert.equal(star.clients[0].localId, 1, 'Client 0 localId');
assert.equal(star.clients[1].localId, 2, 'Client 1 localId');
assert.equal(star.clients[0].id, 1, 'Client 0 id');
assert.equal(star.clients[1].id, 2, 'Client 1 id');

@@ -140,1 +140,5 @@ // clientCount

assert.equal(star.clients[1].clientCount, 2, 'Client 1 clientCount');
star.server.removeClient(star.clients[0]);
sendChange(star, 1);
assert.equal(star.server.clientCount, 1, 'Server clientCount after disconnection');
assert.equal(star.clients[1].clientCount, 1, 'Client 1 clientCount after disconnection');

@@ -29,22 +29,71 @@ (function(exports, undefined) {

editorChange: function canopCodemirrorEditorChange(editor, change, actions) {
var actions = actions || [];
var from = change.from;
var to = change.to;
var added = change.text.join('\n');
var removed = change.removed.join('\n');
var fromIdx = editor.indexFromPos(from);
if (removed.length > 0) {
actions.push([canop.action.stringRemove, [], fromIdx, removed]);
editorChange: function canopCodemirrorEditorChange(editor, changes) {
// The codemirror positions in `changes` correspond to before the change's
// execution. However, the `editor` has the changes applied, so that
// `indexFromPos` only returns the right answer for positions after the
// changes are applied.
var actions = [];
var indexFromPos = function(pos) { return editor.indexFromPos(pos); };
for (var i = changes.length - 1; i >= 0; i--) {
var change = changes[i];
var from = change.from;
var to = change.to;
var added = change.text.join('\n');
var removed = change.removed.join('\n');
indexFromPos = this.updateIdxFromCmPos(indexFromPos, change, added, removed);
var fromIdx = indexFromPos(from);
if (removed.length > 0) {
actions.push([canop.action.stringRemove, [], fromIdx, removed]);
}
if (added.length > 0) {
actions.push([canop.action.stringAdd, [], fromIdx, added]);
}
}
if (added.length > 0) {
actions.push([canop.action.stringAdd, [], fromIdx, added]);
}
if (change.next) {
this.editorChange(editor, change.next, actions);
} else {
this.canopClient.actAtomically(actions);
}
this.canopClient.actAtomically(actions.reverse());
},
// Compare codemirror positions a and b.
cmpCmPos: function canopCompareCodemirrorPosition(a, b) {
if (a.line < b.line) { return -1; }
if (a.line > b.line) { return 1; }
if (a.ch < b.ch) { return -1; }
if (a.ch > b.ch) { return 1; }
return 0;
},
// Is the codemirror position a before b?
cmPosLe: function canopCodemirrorPositionLessOrEqual(a, b) {
return this.cmpCmPos(a, b) <= 0;
},
updateIdxFromCmPos: function canopUpdateIndexFromCodemirrorPosition(
indexFromPos, change, added, removed) {
var self = this;
return function(pos) {
if (self.cmPosLe(pos, change.from)) { return indexFromPos(pos); }
else if (self.cmPosLe(change.to, pos)) {
var ch = 0;
if (change.to.line < pos.line) {
ch = pos.ch;
} else if (change.text.length <= 1) {
ch = pos.ch - (change.to.ch - change.from.ch) + added.length;
} else {
var lastLineAdded = change.text[change.text.length - 1];
ch = pos.ch - change.to.ch + lastLineAdded.length;
}
return indexFromPos({
line: pos.line + change.text.length - 1
- (change.to.line - change.from.line),
ch: ch,
}) + removed.length - added.length;
} else if (change.from.line === pos.line) {
return indexFromPos(change.from) - change.from.ch + pos.ch;
} else {
return indexFromPos(change.from)
+ change.removed.slice(0, pos.line - change.from.line).join('\n').length
+ pos.ch + 1;
}
};
},
cursorActivity: function canopCodemirrorCursorActivity(editor) {

@@ -62,3 +111,3 @@ var self = this;

resetEditor: function canopCodemirrorResetEditor() {
this.editor.off('change', this.editorChange);
this.editor.off('changes', this.editorChange);
this.editor.off('cursorActivity', this.cursorActivity);

@@ -69,3 +118,3 @@ var cursor = this.editor.getCursor();

this.editor.on('cursorActivity', this.cursorActivity);
this.editor.on('change', this.editorChange);
this.editor.on('changes', this.editorChange);
},

@@ -75,9 +124,9 @@

updateEditor: function canopCodemirrorUpdateEditor(delta, posChanges) {
this.editor.off('change', this.editorChange);
this.editor.off('changes', this.editorChange);
this.editor.off('cursorActivity', this.cursorActivity);
var cursor = this.editor.indexFromPos(this.editor.getCursor());
var selections = this.getSelections();
this.applyDelta(delta);
this.updateCursor(posChanges, cursor);
this.setSelections(posChanges, selections);
this.editor.on('cursorActivity', this.cursorActivity);
this.editor.on('change', this.editorChange);
this.editor.on('changes', this.editorChange);
},

@@ -100,7 +149,27 @@

updateCursor: function canopCodemirrorUpdateCursor(posChanges, oldCursor) {
cursor = canop.changePosition(oldCursor, posChanges, true);
this.editor.setCursor(this.editor.posFromIndex(cursor));
getSelections: function canopCodemirrorGetSelections() {
var cmSelections = this.editor.listSelections();
var selections = [];
for (var i = 0; i < cmSelections.length; i++) {
var cmSelection = cmSelections[i];
selections.push({
anchor: this.editor.indexFromPos(cmSelection.anchor),
head: this.editor.indexFromPos(cmSelection.head),
});
}
return selections;
},
setSelections: function canopCodemirrorSetSelections(posChanges, oldSelections) {
var cmSelections = [];
for (var i = 0; i < oldSelections.length; i++) {
var oldSelection = oldSelections[i];
cmSelections.push({
anchor: canop.changePosition(this.editor.posFromIndex(oldSelection.anchor), posChanges, true),
head: canop.changePosition(this.editor.posFromIndex(oldSelection.head), posChanges, true),
});
}
this.editor.setSelections(cmSelections);
},
// UI management to show selection from other participants.

@@ -235,6 +304,6 @@

canop.ui = canop.ui || {};
canop.ui.codemirror = function(client, options) {
return new CanopCodemirror(client, options);
canop.ui.codemirror = function(client, editor) {
return new CanopCodemirror(client, editor);
};
}(this));
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc