✨ New Features
-
$all and System Stream Support: Stream feed iterators now work with
$alland system streams ($streams,$et-*,$ce-*, ...)foreach ($eventStore->forwardStreamFeedIterator('$all') as $entryWithEvent) { // iterate the global event log }
- Iterators request feeds with
embed=bodyand read events directly from the embedded entry data - One HTTP request per page instead of one batch request per page plus one request per event
- Iterators request feeds with
-
Embedded Events on Entries: New
Entry::getEmbeddedEvent(): ?Eventmethod exposes the event embedded in a feed entry when the feed was opened withEntryEmbedMode::BODY
🐛 Bug Fixes
-
Iteration no longer stops on pages without events: A feed page consisting entirely of unresolved linkTos (e.g.
$streamsentries pointing into hard-deleted streams) silently ended iteration even when later pages held valid events; the iterator now keeps navigating until it finds a page with events or runs out of pages -
Stream names are URL-encoded: Stream names containing
?,#,/or other reserved characters were silently mangled — writes toname?oneandname?twoboth landed in streamname. Names are nowrawurlencoded, which also makes streams with/in their name (e.g.$connectors-mngt/state-projection/checkpoints) reachable -
Version conflicts detected without reason phrases:
WrongExpectedVersionExceptionwas recognized only by the HTTP reason phrase, which does not exist in HTTP/2 (e.g. behind a TLS-terminating proxy); theKurrent-CurrentVersion/ES-CurrentVersionresponse header is now checked as well -
valid()beforerewind()no longer throws: Callingvalid()ornext()on a freshly createdStreamFeedIteratorthrew a typed-property initialization error instead of behaving like an unstarted iterator
🔧 Breaking Changes
-
EntryDenormalizer Constructor: Now requires an
EventDenormalizeras second argument to build embedded events// Before new EntryDenormalizer($linkDenormalizer) // After new EntryDenormalizer($linkDenormalizer, $eventDenormalizer)
- Applications using
EventStoreFactorydon't need changes
- Applications using
-
Iterator HTTP behavior:
StreamFeedIteratornow opens feeds withembed=bodyand no longer issues per-event batch requests; entries whose events cannot be resolved (e.g. links into hard-deleted streams) are skipped instead of failing the whole page
🛠️ Improvements
- Event Denormalization:
EventDenormalizerhandles both wrapped (single event read) and embedded (feed entry) formats, decodes JSON-stringdata/metaDatafields, and treats empty metadata asnullconsistently across read paths
📦 Dependencies
- Updated: PHPUnit to ^13.0 (dev dependency)
- Updated: Composer dependencies refreshed
Full Changelog
Full Changelog: v0.21.0...v0.22.0