serendipity_hq/component-then-when
Serendipity HQ's Component Then When adds fluent then() and when() helpers to Laravel components, letting you chain conditional logic and post-processing directly in component definitions. Lightweight and easy to drop in, it means cleaner, more expressive code with less boilerplate.
Architecture fit. The package's domain is narrow and well-bounded: given an attempt count (and optionally a failure history), return the timestamp of the next retry. That is a pure, stateless calculation — the easiest possible thing to embed. However, the description in the request does not match the source material: agents/AGENTS.md states explicitly "This is a Symfony bundle" and describes a Symfony Flex / symfony/* version matrix, a Docker-based PHP matrix, and a rector.php with SymfonySetList. This is not a Laravel package. It will ship a Bundle class, a DI extension, a configuration tree, and service definitions. In Laravel we would consume at most the underlying strategy classes and discard the bundle layer. Architecture fit is therefore conditional: viable as a vendored utility, not viable as an installed framework integration.
Integration feasibility. Feasible but non-trivial. Composer will resolve the package, but Laravel will not auto-register anything, no config is publishable, and no facade or container binding exists. A thin Laravel service provider plus a config file mapping is required, and the strategy objects must be bound manually. The real gate is transitive constraint resolution: the bundle pins multiple Symfony components across a supported matrix, and Laravel already pins its own Symfony component versions. A constraint such as symfony/*: ^8.0 (implied by the "current stable release from minor 0" guidance) will conflict with most current Laravel releases. This must be proven with a throwaway composer require before any design work.
Technical risk. High for a dependency that sits on the retry path of a fault-tolerant system:
Key questions to resolve before commitment.
OptionsResolver, Clock, or DependencyInjection at runtime?composer.json constraint set for PHP and each symfony/* package, and does it resolve cleanly inside our target Laravel version's lock?CHANGELOG we can diff?Stack fit. Poor as a framework integration, acceptable as an embedded calculator. The bundle's Symfony wiring is dead weight in Laravel; only the strategy/value objects carry value. Treat this as a library vendoring exercise, not a package installation. Budget one engineer for a two-day spike.
Migration path. Three options, in order of preference:
backoff, retryUntil, maxExceptions, and Illuminate\Support\Sleep; check whether native primitives cover the requirement before importing anything. If they do, the package adds zero value.composer require it, add a RetryBackoffServiceProvider, bind each strategy behind an interface we own, and publish a config/retry-backoff.php that maps attempt counts to strategy classes. Wrap every call behind our own interface so the package is swappable and cannot leak into domain code.Compatibility. Before any code, validate: (a) PHP floor — the AGENTS instructions use "php": "^8.2" as the minimum, so confirm our fleet is at or above it; (b) Symfony component constraints against the Laravel version we run; (c) that no transitive dependency drags in a conflicting symfony/dependency-injection or symfony/http-kernel. If resolution requires a --with-all-dependencies churn of Laravel's Symfony pins, stop and take option 1.
Sequencing.
composer constraint guard in CI.Maintenance. The dominant cost is not code, it is ownership. With one maintainer and no ecosystem, we should assume upstream can go quiet without notice. That means pinning to an exact version, committing the lockfile, tracking the fork as a maintenance item, and scheduling a quarterly review of upstream activity. If we adopt without forking, add a standing ticket to re-evaluate the constraint matrix on every Laravel major upgrade — Symfony component skew is the most likely breakage vector.
Support. No community, no Stack Overflow corpus, no vendor SLA. Support is entirely first-party: engineers read the source. The documentation footprint in the provided material is agent/contributor guidance, not user documentation — do not expect usage examples or migration guides. Factor roughly half a day of engineer ramp-up into the estimate, plus the adapter work.
Scaling. The calculation itself is negligible — it is arithmetic over an integer attempt count, with no I/O, no state, and no concurrency surface. It will not be your bottleneck. The actual scaling considerations live around it and are our responsibilities:
Carbon per request invites drift and test flakiness.Failure modes.
Ramp-up. Low for the domain, moderate for the integration. One engineer can read the entire source in under a day; the adapter, tests, and decision record are another one to two days. Total cost of adoption is approximately three to four engineer-days for a capability that is likely 20–40 lines if built in-house. That ratio — combined with 2 stars, 0 dependents, a single maintainer, and an anomalous release date — is the core finding: the capability is worth having, this package is not the cheapest way to get it. Recommend the two-day spike with a strong prior toward building the backoff strategy internally behind our own interface, keeping this package as a documented reference implementation.
How can I help you explore Laravel packages today?