From be0ab64b0e34f3076fbd3e61e9650773a737b3ec Mon Sep 17 00:00:00 2001 From: Cees-Jan Kiewiet Date: Mon, 7 Aug 2023 11:29:29 +0200 Subject: [PATCH] Add support for react/promise v3 With v3 come a whole list of [changes](https://github.com/reactphp/promise/releases/tag/v3.0.0) including end of promise chain detection, the removal of the `CancellablePromiseInterface` interface, and type templating. --- composer.json | 5 +++-- phpstan.neon.dist | 8 ++++++++ src/Observable.php | 14 +++++++------- src/Observable/ArrayObservable.php | 1 + src/Observable/IteratorObservable.php | 5 +++++ src/React/Promise.php | 19 +++++++++++-------- .../Rx/Functional/Promise/FromPromiseTest.php | 2 +- 7 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 phpstan.neon.dist diff --git a/composer.json b/composer.json index df3eb4bf..8a0919c0 100644 --- a/composer.json +++ b/composer.json @@ -21,12 +21,13 @@ ], "require": { "php": ">=7.0.0", - "react/promise": "~2.2" + "react/promise": "^3 || ~2.2" }, "require-dev": { "satooshi/php-coveralls": "~1.0", "phpunit/phpunit": "^8.5 || ^9", - "react/event-loop": "^1.0 || ^0.5 || ^0.4.2" + "react/event-loop": "^1.0 || ^0.5 || ^0.4.2", + "phpstan/phpstan": "^1.10" }, "suggest": { "react/event-loop": "Used for scheduling async operations" diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 00000000..18ad3d5e --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,8 @@ +parameters: + level: max + + paths: + - test/types/ + + fileExtensions: + - php \ No newline at end of file diff --git a/src/Observable.php b/src/Observable.php index 79db73ba..1ed18e71 100644 --- a/src/Observable.php +++ b/src/Observable.php @@ -296,15 +296,15 @@ public function mergeAll(): Observable /** * Converts an array to an observable sequence * - * @param array $array + * @param array $array * @param SchedulerInterface $scheduler - * @return ArrayObservable + * @return ObservableInterface * * @demo fromArray/fromArray.php * @operator * @reactivex from */ - public static function fromArray(array $array, SchedulerInterface $scheduler = null): ArrayObservable + public static function fromArray(array $array, SchedulerInterface $scheduler = null): ObservableInterface { return new ArrayObservable($array, $scheduler ?: Scheduler::getDefault()); } @@ -312,9 +312,9 @@ public static function fromArray(array $array, SchedulerInterface $scheduler = n /** * Converts an Iterator into an observable sequence * - * @param \Iterator $iterator + * @param \Iterator $iterator * @param SchedulerInterface $scheduler - * @return IteratorObservable + * @return ObservableInterface * * @demo iterator/iterator.php * @operator @@ -2049,8 +2049,8 @@ public function finally(callable $callback): Observable /** * Converts a promise into an observable * - * @param PromiseInterface $promise - * @return Observable + * @param PromiseInterface $promise + * @return Observable * @throws \InvalidArgumentException * * @demo promise/fromPromise.php diff --git a/src/Observable/ArrayObservable.php b/src/Observable/ArrayObservable.php index 7b1be03e..7d6269ba 100644 --- a/src/Observable/ArrayObservable.php +++ b/src/Observable/ArrayObservable.php @@ -6,6 +6,7 @@ use Rx\DisposableInterface; use Rx\Observable; +use Rx\ObservableInterface; use Rx\ObserverInterface; use Rx\SchedulerInterface; diff --git a/src/Observable/IteratorObservable.php b/src/Observable/IteratorObservable.php index 3bfb3958..dd3b3763 100644 --- a/src/Observable/IteratorObservable.php +++ b/src/Observable/IteratorObservable.php @@ -6,9 +6,14 @@ use Rx\DisposableInterface; use Rx\Observable; +use Rx\ObservableInterface; use Rx\ObserverInterface; use Rx\SchedulerInterface; +/** + * @template T + * @template-implements ObservableInterface + */ class IteratorObservable extends Observable { private $items; diff --git a/src/React/Promise.php b/src/React/Promise.php index c8efacfc..25d597ad 100644 --- a/src/React/Promise.php +++ b/src/React/Promise.php @@ -2,7 +2,6 @@ namespace Rx\React; -use React\Promise\CancellablePromiseInterface; use React\Promise\Promise as ReactPromise; use React\Promise\PromiseInterface; use Rx\Disposable\CallbackDisposable; @@ -11,12 +10,16 @@ use Rx\Observable\AnonymousObservable; use Rx\Subject\AsyncSubject; use React\Promise\Deferred; +use Throwable; +/** + * @template T + */ final class Promise { /** - * @param mixed $value - * @return ReactPromise A promise resolved to $value + * @param T $value + * @return PromiseInterface A promise resolved to $value */ public static function resolved($value): ReactPromise { @@ -27,21 +30,21 @@ public static function resolved($value): ReactPromise /** * @param mixed $exception - * @return ReactPromise A promise rejected with $exception + * @return PromiseInterface A promise rejected with $exception */ public static function rejected($exception): ReactPromise { $d = new Deferred(); - $d->reject($exception); + $d->reject($exception instanceof Throwable ? $exception : new RejectedPromiseException($exception)); return $d->promise(); } /** * Converts an existing observable sequence to React Promise * - * @param ObservableInterface $observable + * @param ObservableInterface $observable * @param Deferred $deferred - * @return ReactPromise + * @return ReactPromise * @throws \InvalidArgumentException */ public static function fromObservable(ObservableInterface $observable, Deferred $deferred = null): ReactPromise @@ -94,7 +97,7 @@ function ($error) use ($subject) { $disp = $subject->subscribe($observer); return new CallbackDisposable(function () use ($p, $disp) { $disp->dispose(); - if ($p instanceof CancellablePromiseInterface) { + if (\method_exists($p, 'cancel')) { $p->cancel(); } }); diff --git a/test/Rx/Functional/Promise/FromPromiseTest.php b/test/Rx/Functional/Promise/FromPromiseTest.php index a3be98da..16483c8e 100644 --- a/test/Rx/Functional/Promise/FromPromiseTest.php +++ b/test/Rx/Functional/Promise/FromPromiseTest.php @@ -40,7 +40,7 @@ function () { */ public function from_promise_failure() { - $p = \React\Promise\reject('error'); + $p = \React\Promise\reject(new RejectedPromiseException('error')); $source = Observable::fromPromise($p);