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

# buffer-composer

## 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

## How to update the composer

Use this repo like you would any other Buffer repo: make changes in a separate branch, ask for code review when necessary, merge PR in master when ready. Storybook will be added to this repo so that we can work on the composer easily in isolation. For now, see the last section of this readme for development tips.

Once changes are into master:

1. Make sure the version number (in package.json) was bumped (we follow [semver](https://semver.org/))
  - This can be done by running `npm version <patch|minor|major|...>` if its not been done already
2. Pull the newest master (which now has your changes)
3. Publish this new version to npm: `npm publish --access public`
4. Update the composer's version number in the other project's package.json dependencies (make `@bufferapp/composer` point to the version you've just published)
5. Now that this other project points to the newest composer version, bundle it up before deploying it:
  - For Web: run `gulp watch/webpack --app contentController` (`watch` for dev env and watch changes, `webpack` for prod env)
  - For Publish:

## 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!

## Dev tips

Without Storybook, there's no super easy way to make changes while getting feedback yet. Here's how I've made it work so far, feel free to add alternative workflows while Storybook makes its way here!

- `buffer-web`:
  - Make desired changes to the composer package
  - Run, in `buffer-composer`: `npm run compile-dev`
  - Copy `/buffer-composer/dist/*` to `/buffer-web/node_modules/@bufferapp/composer/dist` (replace existing files with the new ones)
  - Run, in `buffer-web`: `gulp watch --app contentController` (or stop/restart it if it's already running, it'll copy those bundles to the right place when starting up)

- `buffer-publish`:
  - Make desired changes to the composer package
  - Delete `/buffer-publish/node_modules/@bufferapp/composer` and `/buffer-publish/packages/queue/node_modules/@bufferapp/composer`
  - Copy the whole `/buffer-composer/` directory and drop it in `/buffer-publish/packages/`
  - Rename it from `/buffer-publish/packages/buffer-composer/` to `/buffer-publish/packages/composer/`
  - In `buffer-publish`, run `yarn run bootstrap` then `yarn run watch`
