{"action":"created","issue":{"url":"https://api.github.com/repos/Yomguithereal/baobab/issues/404","labels_url":"https://api.github.com/repos/Yomguithereal/baobab/issues/404/labels{/name}","comments_url":"https://api.github.com/repos/Yomguithereal/baobab/issues/404/comments","events_url":"https://api.github.com/repos/Yomguithereal/baobab/issues/404/events","html_url":"https://github.com/Yomguithereal/baobab/issues/404","id":119415936,"number":404,"title":"First-class reference cursor implementation to improve performance","user":{"login":"atifsyedali","id":8594685,"avatar_url":"https://avatars.githubusercontent.com/u/8594685?v=3","gravatar_id":"","url":"https://api.github.com/users/atifsyedali","html_url":"https://github.com/atifsyedali","followers_url":"https://api.github.com/users/atifsyedali/followers","following_url":"https://api.github.com/users/atifsyedali/following{/other_user}","gists_url":"https://api.github.com/users/atifsyedali/gists{/gist_id}","starred_url":"https://api.github.com/users/atifsyedali/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/atifsyedali/subscriptions","organizations_url":"https://api.github.com/users/atifsyedali/orgs","repos_url":"https://api.github.com/users/atifsyedali/repos","events_url":"https://api.github.com/users/atifsyedali/events{/privacy}","received_events_url":"https://api.github.com/users/atifsyedali/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Yomguithereal/baobab/labels/question","name":"question","color":"cc317c"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":11,"created_at":"2015-11-30T04:12:13Z","updated_at":"2015-12-09T10:16:22Z","closed_at":"2015-12-08T05:53:22Z","body":"Monkey's are great. I find myself using them quite a bit. However, my usage is always about making a reference to some centrally stored data.\r\n\r\nFor example, let's say I have the following tree\r\n\r\ndata\r\n-- messages\r\n---- messageA\r\n------ title: \"This is message A\"\r\n---- messageB\r\n------ title: \"This is message B\"\r\nUI\r\n-- messageListView\r\n---- messageViewA\r\n------ message: monkey to /data/messages/messageA\r\n------ someUiState: true\r\n------ someOtherUiState: false\r\n---- messageViewB\r\n------ message: monkey to /data/messages/messageB\r\n------ someUiState: false\r\n------ someOtherUiState: true\r\n-- NotificationBar\r\n---- newMessagesView\r\n------ message: monkey to /data/messages/messageB\r\n\r\nFrom the above, you can see that two UI widgets can share the same message messageB and still have messageB stored in one place. This is great because now I only have to modify messageB and all UI updates accordingly.\r\n\r\nHowever, it turns out that messageB gets copied into the UI state. I can get around this by storing a version field in messageB that gets updated whenever messageB is updated:\r\n\r\ndata / messages / messageB\r\n-- title: \"This is message A\"\r\n-- version: 42\r\n\r\nAnd then monkey the version field in messageB instead...\r\n\r\nUI / messageListView / messageViewB\r\n-- message: monkey to /data/messages/messageB/version\r\n-- refPath: [\"data\", \"messages\", \"messageB\"]\r\n\r\nNow, whenever I need the messageB in my messageViewB, I simple do:\r\n\r\nvar path = messageViewCursor.get('refPath');\r\nvar message = tree.get(path);\r\n\r\nThis approach has two advantages:\r\n1. I don't need to monkey the entire message AND my views reactively update whenever a message gets updated (assuming message here is an atomic UI component ).\r\n2. I get a modifiable copy of message in my view (monkey data is not modifiable).\r\n\r\n---------------------\r\n\r\nHowever, this approach also has disadvantages:\r\n1. This approach does not work across the parent hierarchy unless you also update the version number for every parent until the root. For example,\r\n\r\ndata\r\n-- version: 123\r\n-- messages\r\n---- version: 456\r\n---- messageA\r\n------ version: 789\r\n\r\nIf I am monkeying data/version, then modifying data/messages/messageA does not update references, unless you recursively change version up the chain. Why does this matter? For example, a messageViewList can have a reference to a messages array, and each item messageItemView in messageViewList references a message in the messages array. If a message changes, the messageItemView queues for a re-render, but the messageViewList does not detect any change. In systems like React, this will effectively mean no re-render at all since messageViewList is the parent that does not rerender.\r\n\r\n2 It's difficult to manage all these version fields yourself in the application layer, especially since there are implicit writes when some parts in the supplied path do not exist.\r\n\r\n-------------\r\n\r\nIt would be really neat to have this functionality natively in Baobab. This might mean adding some hidden fields or maintaining a separate structure internally than the input."},"comment":{"url":"https://api.github.com/repos/Yomguithereal/baobab/issues/comments/163177248","html_url":"https://github.com/Yomguithereal/baobab/issues/404#issuecomment-163177248","issue_url":"https://api.github.com/repos/Yomguithereal/baobab/issues/404","id":163177248,"user":{"login":"Yomguithereal","id":2571951,"avatar_url":"https://avatars.githubusercontent.com/u/2571951?v=3","gravatar_id":"","url":"https://api.github.com/users/Yomguithereal","html_url":"https://github.com/Yomguithereal","followers_url":"https://api.github.com/users/Yomguithereal/followers","following_url":"https://api.github.com/users/Yomguithereal/following{/other_user}","gists_url":"https://api.github.com/users/Yomguithereal/gists{/gist_id}","starred_url":"https://api.github.com/users/Yomguithereal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Yomguithereal/subscriptions","organizations_url":"https://api.github.com/users/Yomguithereal/orgs","repos_url":"https://api.github.com/users/Yomguithereal/repos","events_url":"https://api.github.com/users/Yomguithereal/events{/privacy}","received_events_url":"https://api.github.com/users/Yomguithereal/received_events","type":"User","site_admin":false},"created_at":"2015-12-09T10:16:22Z","updated_at":"2015-12-09T10:16:22Z","body":"You are right @atifsyedali. Baobab is meant to be halfway between immutable/persistent data structures and raw JavaScript object so that one may read the tree's data easily and without requiring the component to deal with more constrained API such as mori or immutable-js' ones. But if you need to deal with vast amount of data that will change fairly fast then yes, you should definitely switch to them.\r\n\r\nIf I can bother you some more, did you find specific points in Baobab that were particularly not performant? You seem to have had quite an experience with things people don't tend to develop very commonly and your insight is therefore very valuable on the subject."}}