{"action":"created","comment":{"url":"https://api.github.com/repos/dcos/dcos-ui/pulls/comments/176746242","pull_request_review_id":106507080,"id":176746242,"diff_hunk":"@@ -0,0 +1,113 @@\n+This package is to be extracted to dcos-ui/data-service.\n+\n+# API v1\n+\n+## Mediator Pattern\n+\n+The [mediator pattern](https://en.wikipedia.org/wiki/Mediator_pattern) is used here\n+to decouple data handling from the view components by encapsulating the way they\n+communicate. \n+\n+With this pattern, a component will receive down all the data `(data down)` it needs via props,\n+and send `events up` so the mediator can perform mutations (represented here as a simple callback). \n+The key concept here is that both the data provider and the view component have no idea how each other work.\n+Only the caller of `renderComponents` understands how it works.  \n+\n+```js\n+  /*\n+   * Receives a stream of React.Component and outputs a single components that \n+   * renders the most recevent event from the Observable.\n+  */\n+  renderComponents(component$: Observable<React.Component>): React.Component;\n+```\n+\n+Here is an example of how it could be used to render a page for `space shuttles`\n+that shows which shuttles are on space, and which are ready to be launched.\n+\n+```js\n+// Imagine we manage a launchpad for interplanetary ships\n+import { shuttles$, launchShuttle } from \"shuttles/streams\";\n+import { Space, LaunchPad, LoadingUI, ErrorMessageUI } from \"ui/components\"\n+import { renderComponents } from \"data-service\"\n+\n+\n+// Merging this streams should be done via graphql in the future\n+// See bellow for the equivalent graphql.\n+const launched$ = shuttles$.filter((sht) => sht.location === \"space\");\n+const nextLaunches$ = shuttles$.filter((sht) => sht.location === \"earth\");\n+const content$ = launched$.combineLatest(nextLaunches$,\n+                          (launched, nextLaunches) => {launched, nextLaunches});\n+\n+// This would be a graphql mutation\n+const launch = (name) => {\n+  launchShuttle({name, launchDate: new Date()})\n+}\n+\n+const components$ = content$.map((data) => \n+                                <World>\n+                                  <LaunchPad shuttles={data.nextLaunches} />\n+                                  <Space shuttles={data.launched} />\n+                                  <LaunchButton onLaunch={launch} />\n+                                </World>)\n+                            .startWith(<LoadingUI />)                                \n+                            .catch((err) => <ErrorMessageUI err>));\n+\n+export default renderComponents(components$);\n+```\n+\n+Notice how easy is to provide error handling whenever an exception happens and how \n+we could start the stream of components providing a loading component.\n+\n+If you would be using graphql, the `content$` would be creted through grpahql and the code\n+would look like:\n+```js\n+// Imagine we manage a launchpad for interplanetary ships\n+import { shuttles$, launchShuttle } from \"shuttles/streams\";\n+import { Space, LaunchPad, LoadingUI, ErrorMessageUI } from \"ui/components\"\n+import { renderComponents } from \"data-service\"\n+\n+import { shuttleSchema } from \"shuttles/schema\";\n+\n+const query = `\n+  query launched($location){ \n+    shuttle(location: $location) {\n+      name\n+      launchDate\n+    } \n+  }\n+  \n+  query nextLaunches($location){ \n+    shuttle(location: $location) {\n+      name\n+    } \n+  }\n+`);\n+\n+const content$ = graphql(query, shuttleSchema); \n+\n+const launchMutation = `\n+  mutation {\n+    launchShip(name: $name, launchDate: $launchDate) {\n+      name\n+      launchDate \n+    }\n+  }\n+`;\n+\n+// This would be a graphql mutation","path":"packages/data-service/README.md","position":97,"original_position":97,"commit_id":"0607182f109fa512b7fd89e2971e88418c0db4a7","original_commit_id":"0607182f109fa512b7fd89e2971e88418c0db4a7","user":{"login":"Fabs","id":10524,"avatar_url":"https://avatars1.githubusercontent.com/u/10524?v=4","gravatar_id":"","url":"https://api.github.com/users/Fabs","html_url":"https://github.com/Fabs","followers_url":"https://api.github.com/users/Fabs/followers","following_url":"https://api.github.com/users/Fabs/following{/other_user}","gists_url":"https://api.github.com/users/Fabs/gists{/gist_id}","starred_url":"https://api.github.com/users/Fabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Fabs/subscriptions","organizations_url":"https://api.github.com/users/Fabs/orgs","repos_url":"https://api.github.com/users/Fabs/repos","events_url":"https://api.github.com/users/Fabs/events{/privacy}","received_events_url":"https://api.github.com/users/Fabs/received_events","type":"User","site_admin":false},"body":"Not anymore, no. ","created_at":"2018-03-23T14:11:16Z","updated_at":"2018-03-23T14:11:16Z","html_url":"https://github.com/dcos/dcos-ui/pull/2841#discussion_r176746242","pull_request_url":"https://api.github.com/repos/dcos/dcos-ui/pulls/2841","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/dcos/dcos-ui/pulls/comments/176746242"},"html":{"href":"https://github.com/dcos/dcos-ui/pull/2841#discussion_r176746242"},"pull_request":{"href":"https://api.github.com/repos/dcos/dcos-ui/pulls/2841"}},"in_reply_to_id":176733721},"pull_request":{"url":"https://api.github.com/repos/dcos/dcos-ui/pulls/2841","id":176341582,"html_url":"https://github.com/dcos/dcos-ui/pull/2841","diff_url":"https://github.com/dcos/dcos-ui/pull/2841.diff","patch_url":"https://github.com/dcos/dcos-ui/pull/2841.patch","issue_url":"https://api.github.com/repos/dcos/dcos-ui/issues/2841","number":2841,"state":"open","locked":false,"title":"DCOS-21752 docs(mediator api): describes the mediator api","user":{"login":"Fabs","id":10524,"avatar_url":"https://avatars1.githubusercontent.com/u/10524?v=4","gravatar_id":"","url":"https://api.github.com/users/Fabs","html_url":"https://github.com/Fabs","followers_url":"https://api.github.com/users/Fabs/followers","following_url":"https://api.github.com/users/Fabs/following{/other_user}","gists_url":"https://api.github.com/users/Fabs/gists{/gist_id}","starred_url":"https://api.github.com/users/Fabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Fabs/subscriptions","organizations_url":"https://api.github.com/users/Fabs/orgs","repos_url":"https://api.github.com/users/Fabs/repos","events_url":"https://api.github.com/users/Fabs/events{/privacy}","received_events_url":"https://api.github.com/users/Fabs/received_events","type":"User","site_admin":false},"body":"Presents an example of the mediator API and some documentation.\r\n\r\nAn implementation of the Settings > Package Repository page using this api is on the go here.\r\n\r\nThis documentation will be merged into `data-layer`. And once we are ok with all the pieces we will merge this integration in master\r\n","created_at":"2018-03-20T22:36:28Z","updated_at":"2018-03-23T14:11:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"34c95e037e458d0285b51b3507aa8f2647eb628b","assignee":null,"assignees":[],"requested_reviewers":[{"login":"nLight","id":186223,"avatar_url":"https://avatars0.githubusercontent.com/u/186223?v=4","gravatar_id":"","url":"https://api.github.com/users/nLight","html_url":"https://github.com/nLight","followers_url":"https://api.github.com/users/nLight/followers","following_url":"https://api.github.com/users/nLight/following{/other_user}","gists_url":"https://api.github.com/users/nLight/gists{/gist_id}","starred_url":"https://api.github.com/users/nLight/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nLight/subscriptions","organizations_url":"https://api.github.com/users/nLight/orgs","repos_url":"https://api.github.com/users/nLight/repos","events_url":"https://api.github.com/users/nLight/events{/privacy}","received_events_url":"https://api.github.com/users/nLight/received_events","type":"User","site_admin":false},{"login":"orlandohohmeier","id":647035,"avatar_url":"https://avatars3.githubusercontent.com/u/647035?v=4","gravatar_id":"","url":"https://api.github.com/users/orlandohohmeier","html_url":"https://github.com/orlandohohmeier","followers_url":"https://api.github.com/users/orlandohohmeier/followers","following_url":"https://api.github.com/users/orlandohohmeier/following{/other_user}","gists_url":"https://api.github.com/users/orlandohohmeier/gists{/gist_id}","starred_url":"https://api.github.com/users/orlandohohmeier/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/orlandohohmeier/subscriptions","organizations_url":"https://api.github.com/users/orlandohohmeier/orgs","repos_url":"https://api.github.com/users/orlandohohmeier/repos","events_url":"https://api.github.com/users/orlandohohmeier/events{/privacy}","received_events_url":"https://api.github.com/users/orlandohohmeier/received_events","type":"User","site_admin":false},{"login":"jaxesn","id":1471144,"avatar_url":"https://avatars0.githubusercontent.com/u/1471144?v=4","gravatar_id":"","url":"https://api.github.com/users/jaxesn","html_url":"https://github.com/jaxesn","followers_url":"https://api.github.com/users/jaxesn/followers","following_url":"https://api.github.com/users/jaxesn/following{/other_user}","gists_url":"https://api.github.com/users/jaxesn/gists{/gist_id}","starred_url":"https://api.github.com/users/jaxesn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jaxesn/subscriptions","organizations_url":"https://api.github.com/users/jaxesn/orgs","repos_url":"https://api.github.com/users/jaxesn/repos","events_url":"https://api.github.com/users/jaxesn/events{/privacy}","received_events_url":"https://api.github.com/users/jaxesn/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":874076449,"url":"https://api.github.com/repos/dcos/dcos-ui/labels/data-layer","name":"data-layer","color":"7E5686","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/dcos/dcos-ui/pulls/2841/commits","review_comments_url":"https://api.github.com/repos/dcos/dcos-ui/pulls/2841/comments","review_comment_url":"https://api.github.com/repos/dcos/dcos-ui/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dcos/dcos-ui/issues/2841/comments","statuses_url":"https://api.github.com/repos/dcos/dcos-ui/statuses/0607182f109fa512b7fd89e2971e88418c0db4a7","head":{"label":"dcos:fabs/dream/DCOS-21643-api-v1","ref":"fabs/dream/DCOS-21643-api-v1","sha":"0607182f109fa512b7fd89e2971e88418c0db4a7","user":{"login":"dcos","id":17648048,"avatar_url":"https://avatars1.githubusercontent.com/u/17648048?v=4","gravatar_id":"","url":"https://api.github.com/users/dcos","html_url":"https://github.com/dcos","followers_url":"https://api.github.com/users/dcos/followers","following_url":"https://api.github.com/users/dcos/following{/other_user}","gists_url":"https://api.github.com/users/dcos/gists{/gist_id}","starred_url":"https://api.github.com/users/dcos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dcos/subscriptions","organizations_url":"https://api.github.com/users/dcos/orgs","repos_url":"https://api.github.com/users/dcos/repos","events_url":"https://api.github.com/users/dcos/events{/privacy}","received_events_url":"https://api.github.com/users/dcos/received_events","type":"Organization","site_admin":false},"repo":{"id":56547504,"name":"dcos-ui","full_name":"dcos/dcos-ui","owner":{"login":"dcos","id":17648048,"avatar_url":"https://avatars1.githubusercontent.com/u/17648048?v=4","gravatar_id":"","url":"https://api.github.com/users/dcos","html_url":"https://github.com/dcos","followers_url":"https://api.github.com/users/dcos/followers","following_url":"https://api.github.com/users/dcos/following{/other_user}","gists_url":"https://api.github.com/users/dcos/gists{/gist_id}","starred_url":"https://api.github.com/users/dcos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dcos/subscriptions","organizations_url":"https://api.github.com/users/dcos/orgs","repos_url":"https://api.github.com/users/dcos/repos","events_url":"https://api.github.com/users/dcos/events{/privacy}","received_events_url":"https://api.github.com/users/dcos/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dcos/dcos-ui","description":"The UI for The Datacenter Operating System","fork":false,"url":"https://api.github.com/repos/dcos/dcos-ui","forks_url":"https://api.github.com/repos/dcos/dcos-ui/forks","keys_url":"https://api.github.com/repos/dcos/dcos-ui/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dcos/dcos-ui/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dcos/dcos-ui/teams","hooks_url":"https://api.github.com/repos/dcos/dcos-ui/hooks","issue_events_url":"https://api.github.com/repos/dcos/dcos-ui/issues/events{/number}","events_url":"https://api.github.com/repos/dcos/dcos-ui/events","assignees_url":"https://api.github.com/repos/dcos/dcos-ui/assignees{/user}","branches_url":"https://api.github.com/repos/dcos/dcos-ui/branches{/branch}","tags_url":"https://api.github.com/repos/dcos/dcos-ui/tags","blobs_url":"https://api.github.com/repos/dcos/dcos-ui/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dcos/dcos-ui/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dcos/dcos-ui/git/refs{/sha}","trees_url":"https://api.github.com/repos/dcos/dcos-ui/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dcos/dcos-ui/statuses/{sha}","languages_url":"https://api.github.com/repos/dcos/dcos-ui/languages","stargazers_url":"https://api.github.com/repos/dcos/dcos-ui/stargazers","contributors_url":"https://api.github.com/repos/dcos/dcos-ui/contributors","subscribers_url":"https://api.github.com/repos/dcos/dcos-ui/subscribers","subscription_url":"https://api.github.com/repos/dcos/dcos-ui/subscription","commits_url":"https://api.github.com/repos/dcos/dcos-ui/commits{/sha}","git_commits_url":"https://api.github.com/repos/dcos/dcos-ui/git/commits{/sha}","comments_url":"https://api.github.com/repos/dcos/dcos-ui/comments{/number}","issue_comment_url":"https://api.github.com/repos/dcos/dcos-ui/issues/comments{/number}","contents_url":"https://api.github.com/repos/dcos/dcos-ui/contents/{+path}","compare_url":"https://api.github.com/repos/dcos/dcos-ui/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dcos/dcos-ui/merges","archive_url":"https://api.github.com/repos/dcos/dcos-ui/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dcos/dcos-ui/downloads","issues_url":"https://api.github.com/repos/dcos/dcos-ui/issues{/number}","pulls_url":"https://api.github.com/repos/dcos/dcos-ui/pulls{/number}","milestones_url":"https://api.github.com/repos/dcos/dcos-ui/milestones{/number}","notifications_url":"https://api.github.com/repos/dcos/dcos-ui/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dcos/dcos-ui/labels{/name}","releases_url":"https://api.github.com/repos/dcos/dcos-ui/releases{/id}","deployments_url":"https://api.github.com/repos/dcos/dcos-ui/deployments","created_at":"2016-04-18T22:48:06Z","updated_at":"2018-03-22T12:44:55Z","pushed_at":"2018-03-23T12:43:46Z","git_url":"git://github.com/dcos/dcos-ui.git","ssh_url":"git@github.com:dcos/dcos-ui.git","clone_url":"https://github.com/dcos/dcos-ui.git","svn_url":"https://github.com/dcos/dcos-ui","homepage":"https://dcos.io/","size":43112,"stargazers_count":171,"watchers_count":171,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":64,"mirror_url":null,"archived":false,"open_issues_count":21,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":64,"open_issues":21,"watchers":171,"default_branch":"master"}},"base":{"label":"dcos:feature/data-layer","ref":"feature/data-layer","sha":"94ae335ffe9aa2c9c0d23cdb6da0de808cfcb51a","user":{"login":"dcos","id":17648048,"avatar_url":"https://avatars1.githubusercontent.com/u/17648048?v=4","gravatar_id":"","url":"https://api.github.com/users/dcos","html_url":"https://github.com/dcos","followers_url":"https://api.github.com/users/dcos/followers","following_url":"https://api.github.com/users/dcos/following{/other_user}","gists_url":"https://api.github.com/users/dcos/gists{/gist_id}","starred_url":"https://api.github.com/users/dcos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dcos/subscriptions","organizations_url":"https://api.github.com/users/dcos/orgs","repos_url":"https://api.github.com/users/dcos/repos","events_url":"https://api.github.com/users/dcos/events{/privacy}","received_events_url":"https://api.github.com/users/dcos/received_events","type":"Organization","site_admin":false},"repo":{"id":56547504,"name":"dcos-ui","full_name":"dcos/dcos-ui","owner":{"login":"dcos","id":17648048,"avatar_url":"https://avatars1.githubusercontent.com/u/17648048?v=4","gravatar_id":"","url":"https://api.github.com/users/dcos","html_url":"https://github.com/dcos","followers_url":"https://api.github.com/users/dcos/followers","following_url":"https://api.github.com/users/dcos/following{/other_user}","gists_url":"https://api.github.com/users/dcos/gists{/gist_id}","starred_url":"https://api.github.com/users/dcos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dcos/subscriptions","organizations_url":"https://api.github.com/users/dcos/orgs","repos_url":"https://api.github.com/users/dcos/repos","events_url":"https://api.github.com/users/dcos/events{/privacy}","received_events_url":"https://api.github.com/users/dcos/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dcos/dcos-ui","description":"The UI for The Datacenter Operating System","fork":false,"url":"https://api.github.com/repos/dcos/dcos-ui","forks_url":"https://api.github.com/repos/dcos/dcos-ui/forks","keys_url":"https://api.github.com/repos/dcos/dcos-ui/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dcos/dcos-ui/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dcos/dcos-ui/teams","hooks_url":"https://api.github.com/repos/dcos/dcos-ui/hooks","issue_events_url":"https://api.github.com/repos/dcos/dcos-ui/issues/events{/number}","events_url":"https://api.github.com/repos/dcos/dcos-ui/events","assignees_url":"https://api.github.com/repos/dcos/dcos-ui/assignees{/user}","branches_url":"https://api.github.com/repos/dcos/dcos-ui/branches{/branch}","tags_url":"https://api.github.com/repos/dcos/dcos-ui/tags","blobs_url":"https://api.github.com/repos/dcos/dcos-ui/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dcos/dcos-ui/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dcos/dcos-ui/git/refs{/sha}","trees_url":"https://api.github.com/repos/dcos/dcos-ui/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dcos/dcos-ui/statuses/{sha}","languages_url":"https://api.github.com/repos/dcos/dcos-ui/languages","stargazers_url":"https://api.github.com/repos/dcos/dcos-ui/stargazers","contributors_url":"https://api.github.com/repos/dcos/dcos-ui/contributors","subscribers_url":"https://api.github.com/repos/dcos/dcos-ui/subscribers","subscription_url":"https://api.github.com/repos/dcos/dcos-ui/subscription","commits_url":"https://api.github.com/repos/dcos/dcos-ui/commits{/sha}","git_commits_url":"https://api.github.com/repos/dcos/dcos-ui/git/commits{/sha}","comments_url":"https://api.github.com/repos/dcos/dcos-ui/comments{/number}","issue_comment_url":"https://api.github.com/repos/dcos/dcos-ui/issues/comments{/number}","contents_url":"https://api.github.com/repos/dcos/dcos-ui/contents/{+path}","compare_url":"https://api.github.com/repos/dcos/dcos-ui/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dcos/dcos-ui/merges","archive_url":"https://api.github.com/repos/dcos/dcos-ui/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dcos/dcos-ui/downloads","issues_url":"https://api.github.com/repos/dcos/dcos-ui/issues{/number}","pulls_url":"https://api.github.com/repos/dcos/dcos-ui/pulls{/number}","milestones_url":"https://api.github.com/repos/dcos/dcos-ui/milestones{/number}","notifications_url":"https://api.github.com/repos/dcos/dcos-ui/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dcos/dcos-ui/labels{/name}","releases_url":"https://api.github.com/repos/dcos/dcos-ui/releases{/id}","deployments_url":"https://api.github.com/repos/dcos/dcos-ui/deployments","created_at":"2016-04-18T22:48:06Z","updated_at":"2018-03-22T12:44:55Z","pushed_at":"2018-03-23T12:43:46Z","git_url":"git://github.com/dcos/dcos-ui.git","ssh_url":"git@github.com:dcos/dcos-ui.git","clone_url":"https://github.com/dcos/dcos-ui.git","svn_url":"https://github.com/dcos/dcos-ui","homepage":"https://dcos.io/","size":43112,"stargazers_count":171,"watchers_count":171,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":64,"mirror_url":null,"archived":false,"open_issues_count":21,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":64,"open_issues":21,"watchers":171,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dcos/dcos-ui/pulls/2841"},"html":{"href":"https://github.com/dcos/dcos-ui/pull/2841"},"issue":{"href":"https://api.github.com/repos/dcos/dcos-ui/issues/2841"},"comments":{"href":"https://api.github.com/repos/dcos/dcos-ui/issues/2841/comments"},"review_comments":{"href":"https://api.github.com/repos/dcos/dcos-ui/pulls/2841/comments"},"review_comment":{"href":"https://api.github.com/repos/dcos/dcos-ui/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dcos/dcos-ui/pulls/2841/commits"},"statuses":{"href":"https://api.github.com/repos/dcos/dcos-ui/statuses/0607182f109fa512b7fd89e2971e88418c0db4a7"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"Fabs"}}