[![view on npm](https://img.shields.io/npm/v/composite-class.svg)](https://www.npmjs.org/package/composite-class)
[![npm module downloads](https://img.shields.io/npm/dt/composite-class.svg)](https://www.npmjs.org/package/composite-class)
[![Build Status](https://travis-ci.org/75lb/composite-class.svg?branch=master)](https://travis-ci.org/75lb/composite-class)
[![Dependency Status](https://badgen.net/david/dep/75lb/composite-class)](https://david-dm.org/75lb/composite-class)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](https://github.com/feross/standard)

# composite-class

An isomorphic, load-anywhere JavaScript class for building [composite structures](https://en.wikipedia.org/wiki/Composite_pattern). Suitable for use as a super class or mixin.

## Synopsis

The `Composite` class implements the [composite design pattern](https://en.wikipedia.org/wiki/Composite_pattern), useful for building and traversing tree structures. For example, build a composite structure representing the French government:

```js
const Composite = require('composite-class')

class Person extends Composite {
  constructor (name, role) {
    super()
    this.name = name
    this.role = role
  }

  toString () {
    return `${this.name} [${this.role}]`
  }
}

const government = new Person('Gouvernement de la République française', 'Government')
const headOfState = new Person('Emmanuel Macron', 'Head of State')
const primeMinister = new Person('Édouard Philippe', 'Prime Minister')
const ministerArmedForces = new Person('Florence Parly', 'Minister of the Armed Forces')
const ministerEconomy = new Person('Bruno Le Maire', 'Minister of Finance and the Economy')

government.add(headOfState)
headOfState.add(primeMinister)
primeMinister.add(ministerArmedForces)
primeMinister.add(ministerEconomy)

console.log(government.tree())
```

Output.

```
- Gouvernement de la République française [Government]
  - Emmanuel Macron [Head of State]
    - Édouard Philippe [Prime Minister]
      - Florence Parly [Minister of the Armed Forces]
      - Bruno Le Maire [Minister of Finance and the Economy]
```

The `Composite` class implements an [iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterator_protocol) interface, therefore can be iterated using standard JavaScript methods.

```js
for (const person of government) {
  console.log('Processing:', person.name)
}
```

Output.

```
Processing: Gouvernement de la République française
Processing: Emmanuel Macron
Processing: Édouard Philippe
Processing: Florence Parly
Processing: Bruno Le Maire
```

{{>main}}

## Load anywhere

This library is compatible with Node.js, the Web and any style of module loader. It can be loaded anywhere, natively without transpilation.

Node.js:

```js
const Composite = require('composite-class')
```

Within Node.js with ECMAScript Module support enabled:

```js
import Composite from 'composite-class'
```

Within an modern browser ECMAScript Module:

```js
import Composite from './node_modules/composite-class/index.mjs'
```

Old browser (adds `window.Composite`):

```html
<script nomodule src="./node_modules/composite-class/dist/index.js"></script>
```

* * *

&copy; 2016-20 Lloyd Brookes \<75pound@gmail.com\>.

Isomorphic test suite by [test-runner](https://github.com/test-runner-js/test-runner) and [web-runner](https://github.com/test-runner-js/web-runner). Documented by [jsdoc-to-markdown](https://github.com/jsdoc2md/jsdoc-to-markdown).
