PHPackages                             flyokai/composition - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. flyokai/composition

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

flyokai/composition
===================

Composition helpers

v1.1.7(3w ago)0341MITPHP

Since Apr 25Pushed 3w agoCompare

[ Source](https://github.com/flyokai/composition)[ Packagist](https://packagist.org/packages/flyokai/composition)[ RSS](/packages/flyokai-composition/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (2)Versions (14)Used By (1)

flyokai/composition
===================

[](#flyokaicomposition)

> User docs → [`README.md`](README.md) · Agent quick-ref → [`CLAUDE.md`](CLAUDE.md) · Agent deep dive → [`AGENTS.md`](AGENTS.md)

> Topological-sort helpers for declaring `before`, `after`, and `depends` relationships between modules and pipeline items.

A thin layer on top of [`marcj/topsort`](https://github.com/marcj/topsort.php) that gives Flyokai a single, consistent way to order things — modules at bootstrap, ACL tuners, indexers, setup steps, anywhere a list needs to be deterministic.

Features
--------

[](#features)

- `sortComposition(array $items)` — sorts items by `before`/`after`/`depends` declarations
- `castCompositionArgument(array $items, string $name, string $key)` — sort + validate, returns ordered class names
- `assertCompositionKeys()` — ensures every item has the keys it must
- `mergeDepends()` — merge &amp; dedupe dependency arrays
- `ArraySortGroup` — extends `MJS\TopSort\Implementations\ArraySort` with grouping for parallel-safe execution

Installation
------------

[](#installation)

```
composer require flyokai/composition
```

Quick start
-----------

[](#quick-start)

```
use function Flyokai\Composition\sortComposition;

$items = [
    'cache'  => ['className' => Cache::class,  'after' => 'config'],
    'config' => ['className' => Config::class],
    'db'     => ['className' => Db::class,     'depends' => 'config'],
    'http'   => ['className' => Http::class,   'before' => 'db'],
];

$sorted = sortComposition($items);

// Returns: ['http', 'config', 'cache', 'db'] — keys preserved, order corrected
```

Item shape
----------

[](#item-shape)

```
[
    'itemName' => [
        'className' => 'Full\\Class\\Name',
        'before'    => 'item2,item3',     // string or array
        'after'     => 'item1',           // string or array
        'depends'   => 'other1,other2',   // string or array
    ]
]
```

MechanismSemantics`before`"this item comes before X" → **X depends on this item**`after`"this item comes after X" → this item depends on X`depends`direct dependency declaration`before` is intentionally inverted — `'before' => 'cache'` means *cache* depends on the current item, not the other way.

Casting to ordered class names
------------------------------

[](#casting-to-ordered-class-names)

```
use function Flyokai\Composition\castCompositionArgument;

$ordered = castCompositionArgument($items, 'modules', 'className');
// ['Http\\Class', 'Config\\Class', 'Cache\\Class', 'Db\\Class']
```

`assertCompositionKeys($items, ['className', 'tag'], 'pipelines')` enforces that every entry contains the listed keys after sorting.

Group sorting
-------------

[](#group-sorting)

```
use Flyokai\Composition\TopSort\ArraySortGroup;

$sorter = new ArraySortGroup();
$sorter->add('a', []);
$sorter->add('b', ['a']);
$sorter->add('c', []);
$sorter->add('d', ['b']);

$sorter->sorted();  // ['a', 'c', 'b', 'd']
$sorter->grouped(); // [['a', 'c'], ['b'], ['d']] — items in a group are independent
```

`grouped()` returns dependency cohorts — every item in a cohort can run in parallel without violating ordering.

Gotchas
-------

[](#gotchas)

- **`before` is inverted.** `'before' => 'cache'` declares *cache* as depending on this item.
- **Missing dependencies throw** — `ElementNotFoundException`. No silent omission.
- **Cycles throw** — `CircularDependencyException` via parent tracking.
- Adding elements after sorting invalidates the cached result; a full re-sort runs on next access.
- Accepts `'a,b'`, `['a','b']`, or empty string interchangeably (empties are filtered out).

See also
--------

[](#see-also)

- [`flyokai/application`](../application/README.md) uses this for module ordering and DB setup steps.
- [amphp-injector](../amphp-injector/README.md) ships its own `CompositionOrdered` for ordered DI compositions, built on the same primitives.

License
-------

[](#license)

MIT

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance91

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity27

Early-stage or recently created project

 Bus Factor1

Top contributor holds 83.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~5 days

Recently: every ~11 days

Total

10

Last Release

25d ago

Major Versions

0.1.0 → v1.1.02026-04-25

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/247743048?v=4)[flyokai](/maintainers/flyokai)[@flyokai](https://github.com/flyokai)

---

Top Contributors

[![flyokai](https://avatars.githubusercontent.com/u/247743048?v=4)](https://github.com/flyokai "flyokai (5 commits)")[![wtsergo](https://avatars.githubusercontent.com/u/305326?v=4)](https://github.com/wtsergo "wtsergo (1 commits)")

### Embed Badge

![Health badge](/badges/flyokai-composition/health.svg)

```
[![Health](https://phpackages.com/badges/flyokai-composition/health.svg)](https://phpackages.com/packages/flyokai-composition)
```

###  Alternatives

[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

751291.4k43](/packages/civicrm-civicrm-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
