{"action":"created","issue":{"url":"https://api.github.com/repos/ianstormtaylor/slate/issues/259","repository_url":"https://api.github.com/repos/ianstormtaylor/slate","labels_url":"https://api.github.com/repos/ianstormtaylor/slate/issues/259/labels{/name}","comments_url":"https://api.github.com/repos/ianstormtaylor/slate/issues/259/comments","events_url":"https://api.github.com/repos/ianstormtaylor/slate/issues/259/events","html_url":"https://github.com/ianstormtaylor/slate/issues/259","id":172142264,"node_id":"MDU6SXNzdWUxNzIxNDIyNjQ=","number":259,"title":"Collaborative editing","user":{"login":"davolokh","id":2715874,"node_id":"MDQ6VXNlcjI3MTU4NzQ=","avatar_url":"https://avatars3.githubusercontent.com/u/2715874?v=4","gravatar_id":"","url":"https://api.github.com/users/davolokh","html_url":"https://github.com/davolokh","followers_url":"https://api.github.com/users/davolokh/followers","following_url":"https://api.github.com/users/davolokh/following{/other_user}","gists_url":"https://api.github.com/users/davolokh/gists{/gist_id}","starred_url":"https://api.github.com/users/davolokh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davolokh/subscriptions","organizations_url":"https://api.github.com/users/davolokh/orgs","repos_url":"https://api.github.com/users/davolokh/repos","events_url":"https://api.github.com/users/davolokh/events{/privacy}","received_events_url":"https://api.github.com/users/davolokh/received_events","type":"User","site_admin":false},"labels":[{"id":434641210,"node_id":"MDU6TGFiZWw0MzQ2NDEyMTA=","url":"https://api.github.com/repos/ianstormtaylor/slate/labels/discussion","name":"discussion","color":"eeeeee","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":61,"created_at":"2016-08-19T14:21:30Z","updated_at":"2018-08-24T08:04:57Z","closed_at":null,"author_association":"NONE","body":"@yatskevich and me did a research and tried to design an appropriate architecture for supporting collaborative editing. There are some key points with explanation below.\n\nThe main idea is to implement a kind of Redux-like behavior within Slate.\n`<Editor store={Store} … />`\nThe goal of having Store is ability to have clear separation and understandable flow.\n\nUseCase: \n- User press key (types symbol)\n- Action is generated\n- Action is dispatched to Store\n- Store updates State\n- setState called\n- Editor re-rendered\n\nThis way allows us to have ability to manage operations in any suitable way (CRDT, OT, etc.) within Store.\n\nLet’s see how to handle text paste operation in more details:\n1. Action `pasteText` dispatched to Store (`data: {position, text}`)\n   No need to get current state, call transform() and return new state. Just dispatch an Action.\n2. Store has a Reducer for handling such an Action\n   If we’re talking about ColloborativeStore - one type, if about SimpleStore - another one. We can even have few implementation of CollaborativeStores (CRDT and OT).\n\nCollaborativeStore:\n- Splits `pasteText` operation into a set of atomic `insertCharacter` operations\n- Applies operations to State\n- Translates this operations set to server\n- Listens for updates from server (i.e. smb else is editing this doc and generates the same type of operations set)\n\nSimpleStore:\n- Applies operations to State (no need to split to atomic operations)\n\nIn our mind such architecture allows Slate to be more flexible and extensible. But this is not a completely analyzed proposal - just an idea. \n\nAnd a few pictures for clarification.\n\nWorkflow Chart:\n![fullsizerender](https://cloud.githubusercontent.com/assets/2715874/17812946/f88bff2e-6631-11e6-8055-1723fe784848.jpg)\n\nImplementation example\n![fullsizerender 5](https://cloud.githubusercontent.com/assets/2715874/17812955/01e4e914-6632-11e6-8b70-b2b299e9a017.jpg)\n\n`pastText` in depth:\n![fullsizerender 3](https://cloud.githubusercontent.com/assets/2715874/17812958/040e3a4c-6632-11e6-8788-cc9cbcb1f531.jpg)\n\nP.S. Possibly, Store should send Transfroms (not Actions) to Server and get Transforms back.\n\n@ianstormtaylor: Could you please take a look at this and share your opinion?\n"},"comment":{"url":"https://api.github.com/repos/ianstormtaylor/slate/issues/comments/415684842","html_url":"https://github.com/ianstormtaylor/slate/issues/259#issuecomment-415684842","issue_url":"https://api.github.com/repos/ianstormtaylor/slate/issues/259","id":415684842,"node_id":"MDEyOklzc3VlQ29tbWVudDQxNTY4NDg0Mg==","user":{"login":"bryanph","id":3816712,"node_id":"MDQ6VXNlcjM4MTY3MTI=","avatar_url":"https://avatars1.githubusercontent.com/u/3816712?v=4","gravatar_id":"","url":"https://api.github.com/users/bryanph","html_url":"https://github.com/bryanph","followers_url":"https://api.github.com/users/bryanph/followers","following_url":"https://api.github.com/users/bryanph/following{/other_user}","gists_url":"https://api.github.com/users/bryanph/gists{/gist_id}","starred_url":"https://api.github.com/users/bryanph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bryanph/subscriptions","organizations_url":"https://api.github.com/users/bryanph/orgs","repos_url":"https://api.github.com/users/bryanph/repos","events_url":"https://api.github.com/users/bryanph/events{/privacy}","received_events_url":"https://api.github.com/users/bryanph/received_events","type":"User","site_admin":false},"created_at":"2018-08-24T08:04:57Z","updated_at":"2018-08-24T08:04:57Z","author_association":"CONTRIBUTOR","body":"Instead of implementing operational transform, perhaps we can start with something simpler, like block-level locking, which locks the block for other users when the user requests a lock on the block."}}
{"actor":{"display_login":"bryanph"}}