/**
  * You can either iterate reading from the start of the stream, beginning at the first event registered and move forward,
  * or you can iterate from the end, meaning that the first iteration will correspond to the latest event registered,
  * and move backward to the beginning of the stream.
  *
  * @param StreamId   $streamId
  * @param HttpClient $client
  * @param bool       $readFromStart
  */
 public function __construct(StreamId $streamId, HttpClient $client, $readFromStart = true)
 {
     $this->streamId = $streamId;
     $this->client = $client;
     $this->headUri = sprintf('streams/%s', $streamId->toString());
     $direction = $readFromStart ? ReadDirection::FORWARD : ReadDirection::BACKWARD;
     $this->readDirection = new ReadDirection($direction);
 }
 /**
  * Retrieves events recorded since a given version of the stream.
  * Does not include the event with number corresponding to the given version.
  *
  * @param string $streamId
  * @param int    $version
  *
  * @return EventRecordCollection
  */
 public function readStreamUpToVersion(string $streamId, int $version) : EventRecordCollection
 {
     if ($version <= 0) {
         throw new \InvalidArgumentException(sprintf('version should be >= 0, got: %d', $version));
     }
     $streamId = new StreamId($streamId);
     // Todo: there are probably more streams to avoid. Thinking of system or metadata streams.
     if ($streamId->toString() === StreamId::ALL) {
         throw new \InvalidArgumentException(sprintf('Can not catch up %s stream.', StreamId::ALL));
     }
     $feedsIterator = new EventStreamFeedIterator($streamId, $this, false);
     $eventsIterator = new EventStreamIterator($feedsIterator);
     $events = [];
     foreach ($eventsIterator as $event) {
         if ($event->getNumber() < $version) {
             throw new \InvalidArgumentException(sprintf('Stream %s has not reached version %d.', $streamId->toString(), $version));
         }
         if ($event->getNumber() === $version) {
             break;
         }
         $events[] = $event;
     }
     $events = array_reverse($events);
     return EventRecordCollection::fromArray($events);
 }
 /**
  * @return RequestInterface
  */
 public function buildRequest() : RequestInterface
 {
     return new Request('DELETE', sprintf('streams/%s', $this->streamId->toString()), [RequestHeader::HARD_DELETE => 'true']);
 }
 /**
  * @return RequestInterface
  */
 public function buildRequest() : RequestInterface
 {
     return new Request('POST', sprintf('streams/%s', $this->streamId->toString()), [RequestHeader::CONTENT_TYPE => ContentType::JSON_ES, RequestHeader::EXPECTED_VERSION => $this->expectedVersion->toInt()], $this->buildBody());
 }