Skip to content

Commit

Permalink
Fixed DeleteLocal & Client Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
R1c4rdCo5t4 committed Mar 24, 2024
1 parent 6a7dfce commit ccef01d
Show file tree
Hide file tree
Showing 19 changed files with 141 additions and 158 deletions.
4 changes: 2 additions & 2 deletions code/client/dev-dist/sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ if (!self.define) {
});
};
}
define(['./workbox-a0f72815'], (function (workbox) { 'use strict';
define(['./workbox-fda11f75'], (function (workbox) { 'use strict';

self.skipWaiting();
workbox.clientsClaim();
Expand All @@ -82,7 +82,7 @@ define(['./workbox-a0f72815'], (function (workbox) { 'use strict';
"revision": "3ca0b8505b4bec776b69afdba2768812"
}, {
"url": "index.html",
"revision": "0.5aj285mkmh8"
"revision": "0.kad9pi711c"
}], {});
workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
Expand Down
118 changes: 57 additions & 61 deletions code/client/src/editor/crdt/fugue.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { type DeleteOperation, type InsertOperation, type StyleOperation } from '@notespace/shared/crdt/types/operations';
import {
type DeleteOperation,
type InsertOperation,
type StyleOperation,
} from '@notespace/shared/crdt/types/operations';
import { type Node, type Id } from '@notespace/shared/crdt/types/nodes';
import { type Style } from '@notespace/shared/crdt/types/styles';
import { FugueTree } from '@notespace/shared/crdt/FugueTree';
import { generateReplicaId } from './utils';
import { socket } from '@src/socket/socket';
import { type InsertNode } from '@editor/crdt/types';
import {Cursor, Selection} from '@editor/slate/model/cursor'
import { isEmpty } from 'lodash';
import { Cursor, Selection } from '@editor/slate/model/cursor';
import { isEmpty, isEqual } from 'lodash';

/**
* A local replica of a FugueTree.
Expand Down Expand Up @@ -37,12 +41,11 @@ export class Fugue {
* @param start
* @param values
*/
insertLocal({start}: Selection, ...values: InsertNode[]): InsertOperation[] {
return values.map((value, i) => {
const operation = this.insertOne({...start, column: start.column + i}, value);
insertLocal(start: Cursor, ...values: InsertNode[]): void {
values.forEach((value, i) => {
const operation = this.getInsertOperation({ ...start, column: start.column + i }, value);
this.addNode(operation);
socket.emit('operation', operation); // FIXME: break data into data chunks - less network traffic
return operation;
socket.emit('operation', operation); // TODO: break data into data chunks - less network traffic
});
}

Expand All @@ -55,20 +58,17 @@ export class Fugue {
}

/**
* Inserts a new node in the tree based on the given operation.
* Gets the insert operation based on the given cursor and insert node.
* @param start - the index where the new node should be inserted
* @param value - the value of the new node
* @param styles
* @private
* @returns the insert operation
*/
private insertOne({ line, column } : Cursor, { value, styles }: InsertNode): InsertOperation {
private getInsertOperation({ line, column }: Cursor, { value, styles }: InsertNode): InsertOperation {
const id = { sender: this.replicaId, counter: this.counter++ };

const root = this.findNode('\n', line) || this.tree.root;

const leftOrigin = column === 0 ? root : this.tree.getByIndex(root, column - 1);

if (isEmpty(leftOrigin.rightChildren)) {
return {
type: 'insert',
Expand All @@ -79,12 +79,10 @@ export class Fugue {
styles,
};
}

const rightOrigin = this.tree.getLeftmostDescendant(leftOrigin.rightChildren[0]);
return { type: 'insert', id, value, parent: rightOrigin.id, side: 'L' };
}


/**
* Inserts a new node in the tree based on the given operation.
* @param id
Expand All @@ -99,25 +97,39 @@ export class Fugue {

/**
* Deletes the nodes from the given start index to the given end index.
* @param start
* @param end (exclusive)
* @param selection
*/
deleteLocal({start, end} : Selection): void {
const deleteElement = (id : Id) => {
const msg = this.deleteOne(id);
this.deleteNode(msg);
socket.emit('operation', msg); // FIXME: this should be done only once after all the deletes - less network traffic
};

const startRoot = this.findNode('\n', start.line);
const startNode = this.tree.getByIndex(startRoot, start.column);

const endRoot = this.findNode('\n', end.line);
const endNode = this.tree.getByIndex(endRoot, end.column);

for (const node of this.tree.traverse(startNode)){
if (node === endNode) break;
deleteElement(node.id);
deleteLocal({ start, end }: Selection): void {
// delete from start to end
let lineCounter = 0;
let columnCounter = 0;
let deleteFlag = false;
for (const node of this.traverseTree()) {
// delete condition
if (
lineCounter === start.line &&
(columnCounter === start.column || (isEqual(start, end) && columnCounter === start.column - 1))
) {
deleteFlag = true;
}
// delete operation
if (deleteFlag) {
const { id } = node;
this.removeNode(id);
const operation: DeleteOperation = { type: 'delete', id };
socket.emit('operation', operation); // TODO: break data into data chunks - less network traffic
}
// end condition
if (lineCounter === end.line && columnCounter === end.column) {
break;
}
// update counters
if (node.value === '\n') {
lineCounter++;
columnCounter = 0;
} else {
columnCounter++;
}
}
}

Expand All @@ -126,25 +138,15 @@ export class Fugue {
* @param operation
*/
deleteRemote(operation: DeleteOperation): void {
this.deleteNode(operation);
this.removeNode(operation.id);
}

/**
* Returns the delete operation
* @param index
* @private
* @returns the delete operation
*/
private deleteOne(id : Id): DeleteOperation {
return { type: 'delete', id };
}

/**
* Deletes the node based on the given operation.
* @param operation
* Deletes the node based on the given node id
* @param id
* @private
*/
private deleteNode({id}: DeleteOperation): void {
private removeNode(id: Id): void {
this.tree.deleteNode(id);
}

Expand All @@ -160,8 +162,7 @@ export class Fugue {
value: value,
};
this.tree.updateStyle(id, style, value);
// TODO: swap to chunked operations
socket.emit('operation', styleOperation);
socket.emit('operation', styleOperation); // TODO: break data into data chunks - less network traffic
}
}

Expand All @@ -175,27 +176,22 @@ export class Fugue {
traverseTree = () => this.tree.traverse(this.tree.root);

findNode(value: string, skip: number): Node<string> {
let lastMatch: Node<string> = this.tree.root
for (const node of this.traverseTree()){
if(node.value === value && !node.isDeleted) {
lastMatch = node
if (--skip === 0) return lastMatch
let lastMatch: Node<string> = this.tree.root;
for (const node of this.traverseTree()) {
if (node.value === value && !node.isDeleted) {
lastMatch = node;
if (--skip === 0) return lastMatch;
}
}
return lastMatch
return lastMatch;
}


/**
* Returns the string representation of the tree.
* @returns the string representation of the tree.
*/
toString(): string {
const values: string[] = [];
for (const node of this.traverseTree()) {
values.push(node.value!);
}
return values.join('');
return this.tree.toString();
}

getElementId(index: number): Id {
Expand Down
2 changes: 1 addition & 1 deletion code/client/src/editor/crdt/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ import { type Style } from '@notespace/shared/crdt/types/styles';
export type InsertNode = {
value: string;
styles: Style[];
}
};
4 changes: 1 addition & 3 deletions code/client/src/editor/crdt/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import _, { range } from 'lodash';
import { range } from 'lodash';
import type { Style } from '@notespace/shared/crdt/types/styles';
import type { InsertNode } from '@editor/crdt/types';

Expand All @@ -18,5 +18,3 @@ export function generateReplicaId() {
export function insertNode(value: string, styles: Style[]): InsertNode {
return { value, styles };
}


6 changes: 3 additions & 3 deletions code/client/src/editor/slate/SlateEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import { withHistory } from 'slate-history';
import useEditor from '@editor/slate/hooks/useEditor';
import { withMarkdown } from '@editor/slate/plugins/markdown/withMarkdown';
import { withNormalize } from './plugins/normalize/withNormalize';
import { toSlate } from '@editor/slate/utils';
import { toSlate } from '@editor/slate/utils/toSlate';

const initialValue = [
{
type: 'paragraph',
children: [{ text: '' }],
},
]
];

function SlateEditor() {
const editor = useEditor(withHistory, withReact, withMarkdown, withNormalize);
Expand All @@ -25,7 +25,7 @@ function SlateEditor() {
const { renderElement, renderLeaf } = useRenderers();

useEvents(fugue, () => {
editor.children = toSlate(fugue.traverseTree)
editor.children = toSlate(fugue.traverseTree);
editor.onChange();
});

Expand Down
33 changes: 17 additions & 16 deletions code/client/src/editor/slate/hooks/useInputHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type React from 'react';
import { type Fugue } from '@editor/crdt/fugue';
import CustomEditor from '@editor/slate/model/CustomEditor';
import { type Editor } from 'slate';
import useSelection from './useSelection';
import {isEqual} from 'lodash'
import {insertNode } from '@src/editor/crdt/utils';
import { getSelection } from '../utils/selection';
import { isEqual } from 'lodash';
import { insertNode } from '@src/editor/crdt/utils';

const hotkeys: Record<string, string> = {
b: 'bold',
Expand All @@ -14,36 +14,37 @@ const hotkeys: Record<string, string> = {
};

function useInputHandlers(editor: Editor, fugue: Fugue) {

function onKeyDown(e: React.KeyboardEvent<HTMLDivElement>) {
function onKeyDown(e: React.KeyboardEvent<HTMLDivElement>) {
if (e.ctrlKey) return shortcutHandler(e);
const {selection} = useSelection(editor);
const {start, end} = selection

const selection = getSelection(editor);
const { start, end } = selection;

switch (e.key) {
case 'Enter':
fugue.insertLocal(selection, insertNode('\n', []));
fugue.insertLocal(start, insertNode('\n', []));
break;
case 'Backspace':
if (isEqual({line: 0, column: 0}, start) && isEqual({line:0, column:0}, end)) break;
case 'Backspace': {
const startPosition = { line: 0, column: 0 };
if (isEqual(startPosition, start) && isEqual(startPosition, end)) break;
fugue.deleteLocal(selection);
break;
}
case 'Tab':
e.preventDefault();
editor.insertText('\t');
fugue.insertLocal(selection, insertNode('\t', []));
fugue.insertLocal(start, insertNode('\t', []));
break;
default:
if (e.key.length !== 1) break;
fugue.insertLocal(selection, insertNode(e.key, []));
fugue.insertLocal(start, insertNode(e.key, []));
break;
}
}

function onPaste(e: React.ClipboardEvent<HTMLDivElement>) {
// const clipboardData = e.clipboardData?.getData('text');
// if (!clipboardData) return;
const clipboardData = e.clipboardData?.getData('text');
if (!clipboardData) return;
// const selection = getSelection();
// fugue.insertLocal(start, insertNode(clipboardData, []));
}
Expand Down
27 changes: 0 additions & 27 deletions code/client/src/editor/slate/hooks/useSelection.ts

This file was deleted.

6 changes: 3 additions & 3 deletions code/client/src/editor/slate/model/CustomEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ const CustomEditor = {
const marks = Editor.marks(editor) as Partial<Record<string, boolean>>;
return marks ? marks[format] : false;
},
toggleMark(editor: Editor, mark : string, fugue: Fugue) {
toggleMark(editor: Editor, mark: string, fugue: Fugue) {
const isActive = CustomEditor.isMarkActive(editor, mark);
Transforms.setNodes(editor, { [mark]: !isActive}, { match: n => Editor.isBlock(editor, n) });
Transforms.setNodes(editor, { [mark]: !isActive }, { match: n => Editor.isBlock(editor, n) });

const [start, end] = getAbsoluteSelection(editor)!;
fugue.updateStyleLocal(start, end, !isActive, mark);
},
Expand Down
14 changes: 7 additions & 7 deletions code/client/src/editor/slate/model/cursor.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export type Cursor = {
line: number;
column: number;
}
line: number;
column: number;
};

export type Selection = {
start: Cursor;
end: Cursor;
}
start: Cursor;
end: Cursor;
};
Loading

0 comments on commit ccef01d

Please sign in to comment.