# Cluster

A Cluster is just a wrapper, a group, of two or more ActiveJS fundamental constructs, [Units](/activejs/fundamentals/units.md), [Systems](/activejs/fundamentals/systems.md), [Actions](/activejs/fundamentals/action.md), or even [Clusters](/activejs/fundamentals/cluster.md).

It creates a master Observable of the combined value of its members by merging all the provided Observable constructs. Whenever any of these wrapped constructs emits a value, Cluster emits a new combined-value.

It also provides direct access to the wrapped constructs through `items` property.\
The ideal use case would be when you need access to the combined value of some ActiveJS constructs as an Observable.

Basically,

* It creates a master Observable of the combined -value of provided members.
* Provides access to its members through the Cluster.
* Provides static access to the combined-value.

See [API reference](https://api.activejs.dev/classes/cluster) for more details.

### Initializing a Cluster:

```typescript
// a ListUnit that saves user's liked things
const userLikesUnit = new ListUnit();

// a DictUnit that saves user's preferences as key:value pairs
const userPreferencesUnit = new DictUnit({initialValue: {humor: 'dark'}});

// create a Cluster to group the above Units together
const userDataCluster = new Cluster({
    userLikesUnit, // using shorthand notation
    userPreferencesUnit
});
```

### Accessing the value:

```typescript
// subscribe for the combined-value
userDataCluster.subscribe(value => console.log(value))

// or access it directly
console.log(userDataCluster.value())

// both of these will log the following
{
    userLikesUnit: [],
    userPreferencesUnit: {humor: 'dark'}
}
```

### Accessing the members through Cluster:

Cluster members can be accessed through the `items` property.

```typescript
console.log(userDataCluster.items.userPreferencesUnit.value());
// logs {humor: 'dark'}

console.log(userDataCluster.items.userLikesUnit.value());
// logs []
```

### **Value propagation:**

Whenever a member of the Cluster emits a value, the Cluster will emit a new combined value.

```typescript
// set a preference to the userPreferencesUnit
userPreferencesUnit.set('favouriteMovie', 'Matrix');

// the Cluster will emit the following value
{
    userLikesUnit: [],
    userPreferencesUnit: {humor: 'dark', favouriteMovie: 'Matrix'}
}



// add some liked things to the userLikesUnit
userLikesUnit.push({id: 42, label: 'puppy'}, {id: 66, label: 'kitten'});

// the Cluster will emit the following value
{
    userLikesUnit: [{id: 42, label: 'puppy'}, {id: 66, label: 'kitten'}],
    userPreferencesUnit: {humor: 'dark', favouriteMovie: 'Matrix'}
}

```

Similarly, we can group any number of Units, Systems, Actions or even Clusters together.

## Notes

* Try to refrain from using the static value accessor `value()` method when the Cluster contains immutable Units because when calling the `value()` method of a Cluster, it internally calls its members' `value()` method, and if members are Immutable Units, those Units would create a clone on every call. It's not a bad thing if used intentionally, but it can add extra overhead if used too often.

## Configuration Options

The configuration options can be passed at the time of instantiation. All the configuration options are optional. Some options can also be set globally. See [Configuration](/activejs/guides/configuration.md) for more details.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.activejs.dev/activejs/fundamentals/cluster.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
