Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Operational Transformation for the Draft.js Editor, experimentation #1

Closed
wants to merge 8 commits into from

Conversation

prenaudin
Copy link
Owner

@prenaudin prenaudin commented Sep 8, 2016

Voici une implémentation d'Operational Transformation basé sur Draft.

ayxssqc0q5

Il y a deux fichiers pour réaliser l'OT:

  • diffContentStateText qui ne fait qu'une OT textuelle, avec jsdiff
  • diffContentStateStyle qui est juste le début de la génération de l'OT avec Text, Styles et Entities, j'y reviens à la fin ( piste Proposition 2, Proposition 1 étant celle à tester en premier )

Inclus dans ce code

  • Le composant EditorInput démontrant comment mettre en place Draft.js avec Redux, le debounce est ici pour conserver une UX performante ( 500ms est élevé mais la sérialisation du state par transit est très consommateur, je n'ai pas creusé encore pour l'améliorer)
  • Le composant EditorLogger qui est un composant non graphique permettant de logger les modifications apporter à l'éditeur
  • Action et Reducer pour redux qui facilite l'application de l'OT est les futures évolutions
  • L'ajout des RichUtils pour modifier le style du texte
  • Une mise en place de tests sur le diffContentStateText pour valider son bon fonctionnement

Améliorations possibles:

  • Ne pas rendre Draft.js côté server, génération d'une erreur de diff car génération d'un uid différent empêchant la reconstitution de l'état côté client, voir Rendering isomorphically  facebookarchive/draft-js#385
  • Voir ce que fait transit et ce qui impacte autant les perfs
  • Poursuivre la génération de l'OT avec le styles et les entities

Références:

Voici deux pistes pour réaliser l'OT avec des attributes comme le style ou les entities:

Proposition 1: Composition d'une OT textuelle et d'une OT sur les attributs

  1. Réaliser l'OT textuel entre previousContentState et contentState
  2. Appliquer cette OT sur le previousContentState
  3. Réaliser une OT sur le style et entities entre previousContentState et contentState
  4. Composer l'OT1 et l'OT2 avec d'avoir une OT finale ou envoyer les deux successivement selon l'effort donné

Proposition 2: Introduire une structure de donnée pour faire un diff dessus

  1. Créer une structure de données représentant chaque caractère avec sa valeur, position, style et entities
  2. Faire le diff entre les deux structures avec un algo de type Meyers
  3. Généré l'OT à partir de ce diff

Réflexion
Pour suivre le model de Draft.js qui est puissant, il faut une structure de données solide embarquant Block, CharacterList, Style, Entities. Alors, il est facile et performant de réaliser une génération d'OT complète et évolutive. Celle-ci pourra ensuite être converti dans le format d'OT choisi pour le transport entre clients.

Cheers mate 🍻

@prenaudin prenaudin closed this Sep 8, 2016
@prenaudin prenaudin reopened this Sep 8, 2016
@prenaudin prenaudin closed this Mar 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant