{"action":"created","comment":{"url":"https://api.github.com/repos/CanopyTax/single-spa/pulls/comments/195910564","pull_request_review_id":129370810,"id":195910564,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDE5NTkxMDU2NA==","diff_hunk":"@@ -0,0 +1,149 @@\n+# Parcels\n+\n+A single-spa parcel is a bundle of functionality (like an application or component) meant to be mounted manually \n+by an application. Parcels use similar methodology as applications but are mounted by a manual function call rather than the activity function.\n+A parcel can be as large as an application or as small as an component and written in \n+any language as long as it exports the correct lifecycle events. In a single-spa world, your SPA contains \n+many registered applications and potentially many parcels. Typically we recommend you mount a parcel within \n+the context of an application because the parcel will be unmounted with the application.\n+\n+## Parcel configuration\n+A parcel is just an object with 3 or 4 functions on it, it can be loaded syncronously or asyncronously.\n+Each function is considered a lifecycle method, `bootstrap`, `mount`, `unmout`, `update` and must return a promise.\n+When creating a parcel it's strongly recommended that you use the [lifecycle helper methods](/docs/single-spa-ecosystem.md#help-for-frameworks).\n+An example of a parcel written in React would look like this:\n+```js\n+// myParcel.js\n+import React from 'react'\n+import ReactDom from 'react-dom'\n+import singleSpaReact from 'single-spa-react'\n+import MyParcelComponent from './my-parcel-component.component.js'\n+export const MyParcel = singleSpaReact({\n+  React,\n+  ReactDom,\n+  rootComponent: MyParcelComponent\n+})\n+\n+// in this case singleSpaReact is taking our inputs and generating an object with the required lifecycles.\n+```\n+Then to use the parcel you just created all you need to do is use the `Parcel` component provided in [single-spa-react](https://github.com/CanopyTax/single-spa-react#parcels)\n+```js\n+// mycomponent.js\n+import { Parcel } from 'single-spa-react'\n+import MyParcel from './myparcel.js'\n+\n+export myComponent extends React.Component {\n+    render () {\n+      return (\n+        <Parcel\n+          config={MyParcel}\n+          { /* optional props */ }\n+          { /* and any extra props you want here */ }\n+        />\n+      )\n+    }\n+}\n+```\n+Note in some cases the optional props are required [additional examples](https://github.com/CanopyTax/single-spa-react#examples)\n+\n+## Parcel Lifecycles\n+Start with [applications](/docs/applications.md#registered-application-lifecycle) to learn more about the functionality of single-spa's lifecycle methods.\n+\n+### Bootstrap\n+This lifecycle function will be called once, right before the parcel is\n+mounted for the first time.\n+\n+```js\n+function bootstrap(props) {\n+  return Promise\n+    .resolve()\n+    .then(() => {\n+        // This is where you do one-time initialization\n+        console.log('bootstrapped!')\n+        });\n+}\n+```\n+\n+### Mount\n+If the parcel is not mounted this lifecycle function is called when ever `mountParcel` is called. When \n+called, this function should create DOM elements, DOM event listeners, etc. to render content to the user.\n+\n+```js\n+function mount(props) {\n+  return Promise\n+    .resolve()\n+    .then(() => {\n+        // This is where you tell a framework (e.g., React) to render some ui to the dom\n+        console.log('mounted!')\n+        });\n+}\n+```\n+\n+### Unmount\n+This lifecycle function will be called whenever the parcel is mounted and one of the following cases is true:\n+- `unmount()` is called\n+- The parent parcel or application is unmounted\n+When called, this function should clean up all DOM elements, DOM event listeners, leaked memory, globals, \n+observable subscriptions, etc. that were created at any point when the parcel was mounted.\n+\n+```js\n+function unmount(props) {\n+  return Promise\n+    .resolve()\n+    .then(() => {\n+        // This is where you tell a framework (e.g., React) to unrender some ui from the dom\n+        console.log('unmounted!');\n+        });\n+}\n+```\n+\n+### Update (optional)\n+This lifecycle function will be called whenever the parcel is mounted, and it needs to be updated.\n+\n+## Example use cases\n+\n+### Modals\n+`App1` handles everything related to contacts (highly cohesive) but somewhere in `App2` we need to create a contact.\n+We could do any number of things to share the functionality between application 1 and 2: \n+- If both are written in the same framework we could export/import components.\n+- We could reimplement creating a contact (loss of cohesion)\n+- We could use single-spa parcels.\n+\n+Exporting a parcel from `App1` that wraps the createContact modal component gives us the ability to share components and behavior across disparate frameworks, without losing application cohesion.\n+App1 can export a modal as a single-spa parcel and App2 can import the parcel and use it easily. One major advantage is that in the below example\n+the parcel/modal from App1 that is being used by App2 will also be unmounted, without unmounting/mounting of App1.\n+\n+```js\n+// App1\n+export const AddContactParcel = {\n+  bootstrap: bootstrapFn,\n+  mount: mountFn,\n+  unmount: unmountFn,\n+}\n+\n+// App2\n+// get the parcel configuration in this case I'm using systemJS and react\n+...\n+componentDidMount() {\n+  SystemJS.import('App1').then(App1 => {\n+    const domElement = document.body\n+    App2MountProps.mountParcel(App1.AddContactParcel, {domElement})\n+  })\n+}\n+...\n+\n+```\n+\n+### Cross Library Components\n+\n+There are a lot of different approaches to share components across libraries. One we use extensively \n+for leaf nodes (buttons, etc) is web components. However once you move beyond a leaf node it's much more difficult \n+to share complex components across different frameworks. Single Spa parcels takes the same concepts of multiple \n+applications written in multiple frameworks and applies that to components.\n+\n+### Imperative Applications","path":"docs/parcels.md","position":144,"original_position":144,"commit_id":"f3c627da7e8f010fee439e19e5b46e364fcf803d","original_commit_id":"f3c627da7e8f010fee439e19e5b46e364fcf803d","user":{"login":"joeldenning","id":5524384,"node_id":"MDQ6VXNlcjU1MjQzODQ=","avatar_url":"https://avatars1.githubusercontent.com/u/5524384?v=4","gravatar_id":"","url":"https://api.github.com/users/joeldenning","html_url":"https://github.com/joeldenning","followers_url":"https://api.github.com/users/joeldenning/followers","following_url":"https://api.github.com/users/joeldenning/following{/other_user}","gists_url":"https://api.github.com/users/joeldenning/gists{/gist_id}","starred_url":"https://api.github.com/users/joeldenning/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joeldenning/subscriptions","organizations_url":"https://api.github.com/users/joeldenning/orgs","repos_url":"https://api.github.com/users/joeldenning/repos","events_url":"https://api.github.com/users/joeldenning/events{/privacy}","received_events_url":"https://api.github.com/users/joeldenning/received_events","type":"User","site_admin":false},"body":"What is this section trying to accomplish? Are you explaining an alternative to parcels?","created_at":"2018-06-16T19:36:18Z","updated_at":"2018-06-16T19:52:46Z","html_url":"https://github.com/CanopyTax/single-spa/pull/206#discussion_r195910564","pull_request_url":"https://api.github.com/repos/CanopyTax/single-spa/pulls/206","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/CanopyTax/single-spa/pulls/comments/195910564"},"html":{"href":"https://github.com/CanopyTax/single-spa/pull/206#discussion_r195910564"},"pull_request":{"href":"https://api.github.com/repos/CanopyTax/single-spa/pulls/206"}}},"pull_request":{"url":"https://api.github.com/repos/CanopyTax/single-spa/pulls/206","id":191846563,"node_id":"MDExOlB1bGxSZXF1ZXN0MTkxODQ2NTYz","html_url":"https://github.com/CanopyTax/single-spa/pull/206","diff_url":"https://github.com/CanopyTax/single-spa/pull/206.diff","patch_url":"https://github.com/CanopyTax/single-spa/pull/206.patch","issue_url":"https://api.github.com/repos/CanopyTax/single-spa/issues/206","number":206,"state":"open","locked":false,"title":"Pr/parcel docs","user":{"login":"TheMcMurder","id":3059715,"node_id":"MDQ6VXNlcjMwNTk3MTU=","avatar_url":"https://avatars1.githubusercontent.com/u/3059715?v=4","gravatar_id":"","url":"https://api.github.com/users/TheMcMurder","html_url":"https://github.com/TheMcMurder","followers_url":"https://api.github.com/users/TheMcMurder/followers","following_url":"https://api.github.com/users/TheMcMurder/following{/other_user}","gists_url":"https://api.github.com/users/TheMcMurder/gists{/gist_id}","starred_url":"https://api.github.com/users/TheMcMurder/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TheMcMurder/subscriptions","organizations_url":"https://api.github.com/users/TheMcMurder/orgs","repos_url":"https://api.github.com/users/TheMcMurder/repos","events_url":"https://api.github.com/users/TheMcMurder/events{/privacy}","received_events_url":"https://api.github.com/users/TheMcMurder/received_events","type":"User","site_admin":false},"body":"","created_at":"2018-05-31T19:09:14Z","updated_at":"2018-06-16T19:52:46Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9be1b2e976862a64df8370ade96e35c1904d7aba","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/CanopyTax/single-spa/pulls/206/commits","review_comments_url":"https://api.github.com/repos/CanopyTax/single-spa/pulls/206/comments","review_comment_url":"https://api.github.com/repos/CanopyTax/single-spa/pulls/comments{/number}","comments_url":"https://api.github.com/repos/CanopyTax/single-spa/issues/206/comments","statuses_url":"https://api.github.com/repos/CanopyTax/single-spa/statuses/f3c627da7e8f010fee439e19e5b46e364fcf803d","head":{"label":"CanopyTax:pr/parcel-docs","ref":"pr/parcel-docs","sha":"f3c627da7e8f010fee439e19e5b46e364fcf803d","user":{"login":"CanopyTax","id":8931373,"node_id":"MDEyOk9yZ2FuaXphdGlvbjg5MzEzNzM=","avatar_url":"https://avatars2.githubusercontent.com/u/8931373?v=4","gravatar_id":"","url":"https://api.github.com/users/CanopyTax","html_url":"https://github.com/CanopyTax","followers_url":"https://api.github.com/users/CanopyTax/followers","following_url":"https://api.github.com/users/CanopyTax/following{/other_user}","gists_url":"https://api.github.com/users/CanopyTax/gists{/gist_id}","starred_url":"https://api.github.com/users/CanopyTax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CanopyTax/subscriptions","organizations_url":"https://api.github.com/users/CanopyTax/orgs","repos_url":"https://api.github.com/users/CanopyTax/repos","events_url":"https://api.github.com/users/CanopyTax/events{/privacy}","received_events_url":"https://api.github.com/users/CanopyTax/received_events","type":"Organization","site_admin":false},"repo":{"id":42915978,"node_id":"MDEwOlJlcG9zaXRvcnk0MjkxNTk3OA==","name":"single-spa","full_name":"CanopyTax/single-spa","owner":{"login":"CanopyTax","id":8931373,"node_id":"MDEyOk9yZ2FuaXphdGlvbjg5MzEzNzM=","avatar_url":"https://avatars2.githubusercontent.com/u/8931373?v=4","gravatar_id":"","url":"https://api.github.com/users/CanopyTax","html_url":"https://github.com/CanopyTax","followers_url":"https://api.github.com/users/CanopyTax/followers","following_url":"https://api.github.com/users/CanopyTax/following{/other_user}","gists_url":"https://api.github.com/users/CanopyTax/gists{/gist_id}","starred_url":"https://api.github.com/users/CanopyTax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CanopyTax/subscriptions","organizations_url":"https://api.github.com/users/CanopyTax/orgs","repos_url":"https://api.github.com/users/CanopyTax/repos","events_url":"https://api.github.com/users/CanopyTax/events{/privacy}","received_events_url":"https://api.github.com/users/CanopyTax/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CanopyTax/single-spa","description":"The javascript metaframework","fork":false,"url":"https://api.github.com/repos/CanopyTax/single-spa","forks_url":"https://api.github.com/repos/CanopyTax/single-spa/forks","keys_url":"https://api.github.com/repos/CanopyTax/single-spa/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CanopyTax/single-spa/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CanopyTax/single-spa/teams","hooks_url":"https://api.github.com/repos/CanopyTax/single-spa/hooks","issue_events_url":"https://api.github.com/repos/CanopyTax/single-spa/issues/events{/number}","events_url":"https://api.github.com/repos/CanopyTax/single-spa/events","assignees_url":"https://api.github.com/repos/CanopyTax/single-spa/assignees{/user}","branches_url":"https://api.github.com/repos/CanopyTax/single-spa/branches{/branch}","tags_url":"https://api.github.com/repos/CanopyTax/single-spa/tags","blobs_url":"https://api.github.com/repos/CanopyTax/single-spa/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CanopyTax/single-spa/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CanopyTax/single-spa/git/refs{/sha}","trees_url":"https://api.github.com/repos/CanopyTax/single-spa/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CanopyTax/single-spa/statuses/{sha}","languages_url":"https://api.github.com/repos/CanopyTax/single-spa/languages","stargazers_url":"https://api.github.com/repos/CanopyTax/single-spa/stargazers","contributors_url":"https://api.github.com/repos/CanopyTax/single-spa/contributors","subscribers_url":"https://api.github.com/repos/CanopyTax/single-spa/subscribers","subscription_url":"https://api.github.com/repos/CanopyTax/single-spa/subscription","commits_url":"https://api.github.com/repos/CanopyTax/single-spa/commits{/sha}","git_commits_url":"https://api.github.com/repos/CanopyTax/single-spa/git/commits{/sha}","comments_url":"https://api.github.com/repos/CanopyTax/single-spa/comments{/number}","issue_comment_url":"https://api.github.com/repos/CanopyTax/single-spa/issues/comments{/number}","contents_url":"https://api.github.com/repos/CanopyTax/single-spa/contents/{+path}","compare_url":"https://api.github.com/repos/CanopyTax/single-spa/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CanopyTax/single-spa/merges","archive_url":"https://api.github.com/repos/CanopyTax/single-spa/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CanopyTax/single-spa/downloads","issues_url":"https://api.github.com/repos/CanopyTax/single-spa/issues{/number}","pulls_url":"https://api.github.com/repos/CanopyTax/single-spa/pulls{/number}","milestones_url":"https://api.github.com/repos/CanopyTax/single-spa/milestones{/number}","notifications_url":"https://api.github.com/repos/CanopyTax/single-spa/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CanopyTax/single-spa/labels{/name}","releases_url":"https://api.github.com/repos/CanopyTax/single-spa/releases{/id}","deployments_url":"https://api.github.com/repos/CanopyTax/single-spa/deployments","created_at":"2015-09-22T06:34:46Z","updated_at":"2018-06-15T18:21:09Z","pushed_at":"2018-06-14T16:28:11Z","git_url":"git://github.com/CanopyTax/single-spa.git","ssh_url":"git@github.com:CanopyTax/single-spa.git","clone_url":"https://github.com/CanopyTax/single-spa.git","svn_url":"https://github.com/CanopyTax/single-spa","homepage":"","size":5881,"stargazers_count":1009,"watchers_count":1009,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":94,"mirror_url":null,"archived":false,"open_issues_count":25,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":94,"open_issues":25,"watchers":1009,"default_branch":"master"}},"base":{"label":"CanopyTax:4.0","ref":"4.0","sha":"9cd0587e8a11faeb85aa10ed798a16edd86fc002","user":{"login":"CanopyTax","id":8931373,"node_id":"MDEyOk9yZ2FuaXphdGlvbjg5MzEzNzM=","avatar_url":"https://avatars2.githubusercontent.com/u/8931373?v=4","gravatar_id":"","url":"https://api.github.com/users/CanopyTax","html_url":"https://github.com/CanopyTax","followers_url":"https://api.github.com/users/CanopyTax/followers","following_url":"https://api.github.com/users/CanopyTax/following{/other_user}","gists_url":"https://api.github.com/users/CanopyTax/gists{/gist_id}","starred_url":"https://api.github.com/users/CanopyTax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CanopyTax/subscriptions","organizations_url":"https://api.github.com/users/CanopyTax/orgs","repos_url":"https://api.github.com/users/CanopyTax/repos","events_url":"https://api.github.com/users/CanopyTax/events{/privacy}","received_events_url":"https://api.github.com/users/CanopyTax/received_events","type":"Organization","site_admin":false},"repo":{"id":42915978,"node_id":"MDEwOlJlcG9zaXRvcnk0MjkxNTk3OA==","name":"single-spa","full_name":"CanopyTax/single-spa","owner":{"login":"CanopyTax","id":8931373,"node_id":"MDEyOk9yZ2FuaXphdGlvbjg5MzEzNzM=","avatar_url":"https://avatars2.githubusercontent.com/u/8931373?v=4","gravatar_id":"","url":"https://api.github.com/users/CanopyTax","html_url":"https://github.com/CanopyTax","followers_url":"https://api.github.com/users/CanopyTax/followers","following_url":"https://api.github.com/users/CanopyTax/following{/other_user}","gists_url":"https://api.github.com/users/CanopyTax/gists{/gist_id}","starred_url":"https://api.github.com/users/CanopyTax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CanopyTax/subscriptions","organizations_url":"https://api.github.com/users/CanopyTax/orgs","repos_url":"https://api.github.com/users/CanopyTax/repos","events_url":"https://api.github.com/users/CanopyTax/events{/privacy}","received_events_url":"https://api.github.com/users/CanopyTax/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CanopyTax/single-spa","description":"The javascript metaframework","fork":false,"url":"https://api.github.com/repos/CanopyTax/single-spa","forks_url":"https://api.github.com/repos/CanopyTax/single-spa/forks","keys_url":"https://api.github.com/repos/CanopyTax/single-spa/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CanopyTax/single-spa/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CanopyTax/single-spa/teams","hooks_url":"https://api.github.com/repos/CanopyTax/single-spa/hooks","issue_events_url":"https://api.github.com/repos/CanopyTax/single-spa/issues/events{/number}","events_url":"https://api.github.com/repos/CanopyTax/single-spa/events","assignees_url":"https://api.github.com/repos/CanopyTax/single-spa/assignees{/user}","branches_url":"https://api.github.com/repos/CanopyTax/single-spa/branches{/branch}","tags_url":"https://api.github.com/repos/CanopyTax/single-spa/tags","blobs_url":"https://api.github.com/repos/CanopyTax/single-spa/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CanopyTax/single-spa/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CanopyTax/single-spa/git/refs{/sha}","trees_url":"https://api.github.com/repos/CanopyTax/single-spa/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CanopyTax/single-spa/statuses/{sha}","languages_url":"https://api.github.com/repos/CanopyTax/single-spa/languages","stargazers_url":"https://api.github.com/repos/CanopyTax/single-spa/stargazers","contributors_url":"https://api.github.com/repos/CanopyTax/single-spa/contributors","subscribers_url":"https://api.github.com/repos/CanopyTax/single-spa/subscribers","subscription_url":"https://api.github.com/repos/CanopyTax/single-spa/subscription","commits_url":"https://api.github.com/repos/CanopyTax/single-spa/commits{/sha}","git_commits_url":"https://api.github.com/repos/CanopyTax/single-spa/git/commits{/sha}","comments_url":"https://api.github.com/repos/CanopyTax/single-spa/comments{/number}","issue_comment_url":"https://api.github.com/repos/CanopyTax/single-spa/issues/comments{/number}","contents_url":"https://api.github.com/repos/CanopyTax/single-spa/contents/{+path}","compare_url":"https://api.github.com/repos/CanopyTax/single-spa/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CanopyTax/single-spa/merges","archive_url":"https://api.github.com/repos/CanopyTax/single-spa/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CanopyTax/single-spa/downloads","issues_url":"https://api.github.com/repos/CanopyTax/single-spa/issues{/number}","pulls_url":"https://api.github.com/repos/CanopyTax/single-spa/pulls{/number}","milestones_url":"https://api.github.com/repos/CanopyTax/single-spa/milestones{/number}","notifications_url":"https://api.github.com/repos/CanopyTax/single-spa/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CanopyTax/single-spa/labels{/name}","releases_url":"https://api.github.com/repos/CanopyTax/single-spa/releases{/id}","deployments_url":"https://api.github.com/repos/CanopyTax/single-spa/deployments","created_at":"2015-09-22T06:34:46Z","updated_at":"2018-06-15T18:21:09Z","pushed_at":"2018-06-14T16:28:11Z","git_url":"git://github.com/CanopyTax/single-spa.git","ssh_url":"git@github.com:CanopyTax/single-spa.git","clone_url":"https://github.com/CanopyTax/single-spa.git","svn_url":"https://github.com/CanopyTax/single-spa","homepage":"","size":5881,"stargazers_count":1009,"watchers_count":1009,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":94,"mirror_url":null,"archived":false,"open_issues_count":25,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":94,"open_issues":25,"watchers":1009,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/CanopyTax/single-spa/pulls/206"},"html":{"href":"https://github.com/CanopyTax/single-spa/pull/206"},"issue":{"href":"https://api.github.com/repos/CanopyTax/single-spa/issues/206"},"comments":{"href":"https://api.github.com/repos/CanopyTax/single-spa/issues/206/comments"},"review_comments":{"href":"https://api.github.com/repos/CanopyTax/single-spa/pulls/206/comments"},"review_comment":{"href":"https://api.github.com/repos/CanopyTax/single-spa/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/CanopyTax/single-spa/pulls/206/commits"},"statuses":{"href":"https://api.github.com/repos/CanopyTax/single-spa/statuses/f3c627da7e8f010fee439e19e5b46e364fcf803d"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"joeldenning"}}