[![](https://img.shields.io/npm/v/@bufferapp/composer.svg)](https://www.npmjs.com/package/@bufferapp/composer)

# buffer-composer

## How to publish a new version (Step 1)

Start by making your changes in a new branch, then create a PR, ask for a code review, and finally merge that PR into `master` when ready. Once your changes are merged into `master` it's time to prepare and publish to NPM.

1. Bump the version number (in [`package.json`](/package.json)), following [semver](https://semver.org/).
   - (If you already did this in your branch before merging, you can skip this step.)
   - One quick way to bump the version is with `npm version <patch|minor|major>`
   - You can also bump the version number manually in the `package.json`.
2. Update the [CHANGELOG.md](/CHANGELOG.md) following the pattern we have there and note whatever you've changed, removed, or added.
3. Ensure you push/pull up all changes to GitHub. The idea is that `master` branch should always reflect whatever is latest on NPM. 
4. Now, on the `master` branch, run the comand to publish: 

```
npm publish --access public
```

If all goes well, you should see a message in your terminal letting you know that a new version has been published! When you're ready you can now update the composer version in Buffer Publish so customers can see your changes. Read the next section for more on that.

## How to update the composer in `buffer-publish` (Step 2)

1. Create a new branch in `buffer-publish`. 
2. Change the version of the composer referenced in [`buffer-publish/packages/composer-popover/package.json`](https://github.com/bufferapp/buffer-publish/blob/bc1bda92ed325e499a062480126ff24fec287d7b/packages/composer-popover/package.json#L11)
3. Run `yarn` and then `yarn run watch` to test and confirm your changes work locally.
4. Push the branch to GitHub and create a PR.
5. Confirm your changes work in the staging environment that is spun up from your PR.
6. When ready, merge your PR into buffer-publish's `master` branch – this will trigger a deploy to production! 🎉

## How the composer is consumed

The composer is the same across all projects. However each project has its own set of specificities,
so this package offers a tailored interface for each project the composer is currently being used in.

Here's how the composer is being used across our apps:

- `buffer-publish`: The Publish interface is nothing more than a `Composer` React component that you
  can drop anywhere in the app and pass props to. It's exported as `bufferPublishComposer` from `@bufferapp/composer`. Publish will import those source files and build them; the JS is imported into Publish's larger JS bundle, the CSS is transformed and bundled in a separate CSS file.

- `buffer-web`: When the composer package is published to npm, JS and CSS bundles are generated at the same time: `composer-web-iframe-bundle.js`, `composer-web-iframe-bundle.css`, and `composer-web-iframe-utils.js`. During the Web build process, the "iframe bundles" (`composer-web-iframe-bundle.js` & `composer-web-iframe-bundle.css`) are copied over to the assets directory, to be served to the browser as is. The "iframe utils" bundle (`composer-web-iframe-utils.js`), however, is imported into Web's `content_controller.js` to access utility methods that the dashboard needs to handle the Web composer's iframe setup and communication with the composer. How this works when the Web dashboard loads in a browser: an hidden iframe is created without slowing down the loading of the rest of the dashboard, pre-loading the composer (served from buffer.com/add) inside of it. Web's content controller uses `postMessage` to init the composer with the appropriate data when desired, also showing/hiding its wrapper iframe as needed.

- `buffer-extensions`: Down the road we're also hoping this package can pave the way to native browser extensions, instead of the iframe we're currently using, which would make our extensions much faster.

Search for "@bufferapp/composer" in any of those repos to see examples of how the Composer is currently being used!

## Repo Structure

- `composer/`: the composer itself, exports a React component; should only be consumed in this package
- `interfaces/`: composer wrappers; use those wrappers to make use of the composer in a project; interfaces are named according to their target environment (e.g. `buffer-publish.jsx` for Publish)
  - `utils/`: wrapper utilities; for some projects, e.g. buffer-web with its iframe approach, an extra set of helpers is needed on the other side of the frame, for communication and whatnot: this is it
