<commit_before><?php
/**
 * This file is part of the daikon-cqrs/cqrs project.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

declare(strict_types=1);

namespace Daikon\EventSourcing\EventStore\Commit;

use Daikon\EventSourcing\EventStore\Stream\StreamRevision;
use Ds\Vector;
use Iterator;

final class CommitSequence implements CommitSequenceInterface
{
    /** @var Vector */
    private $compositeVector;

    public static function fromArray(array $commitsArray): CommitSequenceInterface
    {
        return new static(array_map(function (array $commitState): CommitInterface {
            return Commit::fromArray($commitState);
        }, $commitsArray));
    }

    public static function makeEmpty(): CommitSequenceInterface
    {
        return new self;
    }

    public function __construct(array $commits = [])
    {
        $this->compositeVector = (function (CommitInterface ...$commits): Vector {
            return new Vector($commits);
        })(...$commits);
    }

    public function push(CommitInterface $commit): CommitSequenceInterface
    {
        if (!$this->isEmpty()) {
            $nextRevision = $this->getHead()->getAggregateRevision()->increment();
            if (!$nextRevision->equals($commit->getAggregateRevision())) {
                throw new \Exception(sprintf(
                    'Trying to add unexpected revision %s to event-sequence. Expected revision is %s',
                    $commit->getAggregateRevision(),
                    $nextRevision
                ));
            }
        }
        $commitSequence = clone $this;
        $commitSequence->compositeVector->push($commit);
        return $commitSequence;
    }<commit_msg>use AR tail instead of head when pushing onto stream<commit_after><?php
/**
 * This file is part of the daikon-cqrs/cqrs project.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

declare(strict_types=1);

namespace Daikon\EventSourcing\EventStore\Commit;

use Daikon\EventSourcing\EventStore\Stream\StreamRevision;
use Ds\Vector;
use Iterator;

final class CommitSequence implements CommitSequenceInterface
{
    /** @var Vector */
    private $compositeVector;

    public static function fromArray(array $commitsArray): CommitSequenceInterface
    {
        return new static(array_map(function (array $commitState): CommitInterface {
            return Commit::fromArray($commitState);
        }, $commitsArray));
    }

    public static function makeEmpty(): CommitSequenceInterface
    {
        return new self;
    }

    public function __construct(array $commits = [])
    {
        $this->compositeVector = (function (CommitInterface ...$commits): Vector {
            return new Vector($commits);
        })(...$commits);
    }

    public function push(CommitInterface $commit): CommitSequenceInterface
    {
        if (!$this->isEmpty()) {
            $nextRevision = $this->getHead()->getAggregateRevision()->increment();
            if (!$nextRevision->equals($commit->getEventLog()->getTailRevision())) {
                throw new \Exception(sprintf(
                    'Trying to add unexpected revision %s to event-sequence. Expected revision is %s',
                    $commit->getEventLog()->getTailRevision(),
                    $nextRevision
                ));
            }
        }
        $commitSequence = clone $this;
        $commitSequence->compositeVector->push($commit);
        return $commitSequence;
    }
{'fraction_non_alphanumeric': 0.10818307905686546, 'fraction_numerical': 0.0005547850208044383, 'mean_word_length': 2.702258726899384, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7545065', 'n_tokens_mistral': 934, 'n_tokens_neox': 916, 'n_words': 241}