diff --git a/baseline.xml b/baseline.xml
index 7e58717d8..1fcbb2984 100644
--- a/baseline.xml
+++ b/baseline.xml
@@ -64,18 +64,18 @@
errorContext]]>
-
-
- projectors]]>
-
-
-
+
$method
$method
$method
+
+
+ projectors]]>
+
+
new WeakMap()
diff --git a/docs/pages/projection.md b/docs/pages/projection.md
index 9c89d8bd7..06a6f514b 100644
--- a/docs/pages/projection.md
+++ b/docs/pages/projection.md
@@ -118,12 +118,7 @@ Otherwise the projectionist will not recognize that the projection has changed a
To do this, you can add a version to the `projectorId`:
```php
-use Doctrine\DBAL\Connection;
-use Patchlevel\EventSourcing\Attribute\Setup;
-use Patchlevel\EventSourcing\Attribute\Teardown;
-use Patchlevel\EventSourcing\Attribute\Handle;
use Patchlevel\EventSourcing\Attribute\Projector;
-use Patchlevel\EventSourcing\EventBus\Message;
#[Projector('profile_1')]
final class ProfileProjector
@@ -140,16 +135,20 @@ final class ProfileProjector
You can also use the `ProjectorUtil` to build the table/collection name.
-## Projector Repository
+## From Now
-The projector repository is responsible for managing the projectors.
+Certain projectors operate exclusively on post-release events, disregarding historical data.
+Consider, for instance, the scenario of launching a fresh email service.
+Its primary function is to dispatch welcome emails to newly registered users triggered by a `ProfileCreated` event.
```php
-use Patchlevel\EventSourcing\Projection\Projector\InMemoryProjectorRepository;
+use Patchlevel\EventSourcing\Attribute\Projector;
-$projectorRepository = new InMemoryProjectorRepository([
- new ProfileProjection($connection)
-]);
+#[Projector('profile_1', fromNow: true)]
+final class WelcomeEmailProjector
+{
+ // ...
+}
```
## Projectionist
@@ -305,7 +304,7 @@ use Patchlevel\EventSourcing\Projection\Projectionist\DefaultProjectionist;
$projectionist = new DefaultProjectionist(
$eventStore,
$projectionStore,
- $projectorRepository
+ [$projector1, $projector2, $projector3]
);
```
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index dcf8c680d..8d4101dc7 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -15,11 +15,6 @@ parameters:
count: 1
path: src/Projection/Projection/Store/DoctrineStore.php
- -
- message: "#^Method Patchlevel\\\\EventSourcing\\\\Projection\\\\Projector\\\\InMemoryProjectorRepository\\:\\:projectors\\(\\) should return array\\ but returns array\\\\.$#"
- count: 1
- path: src/Projection/Projector/InMemoryProjectorRepository.php
-
-
message: "#^Parameter \\#2 \\$data of method Patchlevel\\\\Hydrator\\\\Hydrator\\:\\:hydrate\\(\\) expects array\\, mixed given\\.$#"
count: 1
diff --git a/src/Attribute/Projector.php b/src/Attribute/Projector.php
index c4ed7011d..2661aced8 100644
--- a/src/Attribute/Projector.php
+++ b/src/Attribute/Projector.php
@@ -11,6 +11,7 @@ final class Projector
{
public function __construct(
public readonly string $id,
+ public readonly bool $fromNow = false,
) {
}
}
diff --git a/src/Metadata/Projector/AttributeProjectorMetadataFactory.php b/src/Metadata/Projector/AttributeProjectorMetadataFactory.php
index 06d2072f0..5cd10bd69 100644
--- a/src/Metadata/Projector/AttributeProjectorMetadataFactory.php
+++ b/src/Metadata/Projector/AttributeProjectorMetadataFactory.php
@@ -79,6 +79,7 @@ public function metadata(string $projector): ProjectorMetadata
$metadata = new ProjectorMetadata(
$projectorInfo->id,
+ $projectorInfo->fromNow,
$subscribeMethods,
$createMethod,
$dropMethod,
diff --git a/src/Metadata/Projector/ProjectorMetadata.php b/src/Metadata/Projector/ProjectorMetadata.php
index 251ea0155..265f4cf89 100644
--- a/src/Metadata/Projector/ProjectorMetadata.php
+++ b/src/Metadata/Projector/ProjectorMetadata.php
@@ -8,6 +8,7 @@ final class ProjectorMetadata
{
public function __construct(
public readonly string $id,
+ public readonly bool $fromNow = false,
/** @var array> */
public readonly array $subscribeMethods = [],
public readonly string|null $setupMethod = null,
diff --git a/src/Projection/Projectionist/DefaultProjectionist.php b/src/Projection/Projectionist/DefaultProjectionist.php
index 915b297de..1367bb7d5 100644
--- a/src/Projection/Projectionist/DefaultProjectionist.php
+++ b/src/Projection/Projectionist/DefaultProjectionist.php
@@ -4,21 +4,24 @@
namespace Patchlevel\EventSourcing\Projection\Projectionist;
+use Closure;
+use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\EventBus\Message;
+use Patchlevel\EventSourcing\Metadata\Projector\AttributeProjectorMetadataFactory;
+use Patchlevel\EventSourcing\Metadata\Projector\ProjectorMetadataFactory;
use Patchlevel\EventSourcing\Projection\Projection\Projection;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionCollection;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionCriteria;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionError;
use Patchlevel\EventSourcing\Projection\Projection\ProjectionStatus;
use Patchlevel\EventSourcing\Projection\Projection\Store\ProjectionStore;
-use Patchlevel\EventSourcing\Projection\Projector\MetadataProjectorResolver;
-use Patchlevel\EventSourcing\Projection\Projector\ProjectorRepository;
-use Patchlevel\EventSourcing\Projection\Projector\ProjectorResolver;
use Patchlevel\EventSourcing\Store\Criteria;
use Patchlevel\EventSourcing\Store\Store;
use Psr\Log\LoggerInterface;
use Throwable;
+use function array_map;
+use function array_merge;
use function sprintf;
final class DefaultProjectionist implements Projectionist
@@ -26,13 +29,14 @@ final class DefaultProjectionist implements Projectionist
private const RETRY_LIMIT = 5;
/** @var array|null */
- private array|null $projectors = null;
+ private array|null $projectorIndex = null;
+ /** @param iterable