Skip to content
2 changes: 1 addition & 1 deletion config/params.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Yiisoft\Yii\Debug\Api\Inspector\Command\PsalmCommand;

$testCommands = [];
if (class_exists(\PHPUnit\Framework\Test::class)) {
if (class_exists(PHPUnit\Framework\Test::class)) {
$testCommands[PHPUnitCommand::COMMAND_NAME] = PHPUnitCommand::class;
}
if (class_exists(Extension::class)) {
Expand Down
4 changes: 4 additions & 0 deletions config/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Yiisoft\Yii\Debug\Api\Inspector\Controller\CacheController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\CommandController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\ComposerController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\DebugServerController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\GitController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\InspectController;
use Yiisoft\Yii\Debug\Api\Inspector\Controller\OpcacheController;
Expand Down Expand Up @@ -58,6 +59,9 @@ static function (ResponseFactoryInterface $responseFactory, ValidatorInterface $
Route::get('/event-stream')
->action([DebugController::class, 'eventStream'])
->name('event-stream'),
Route::get('/dev')
->action([DebugServerController::class, 'stream'])
->name('stream'),
),
Group::create('/inspect/api')
->withCors(CorsAllowAll::class)
Expand Down
9 changes: 5 additions & 4 deletions src/Debug/Controller/DebugController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Yiisoft\Yii\Debug\Api\Debug\Controller;

use OpenApi\Attributes as OA;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
Expand All @@ -12,6 +13,7 @@
use Yiisoft\Assets\AssetPublisherInterface;
use Yiisoft\DataResponse\DataResponse;
use Yiisoft\DataResponse\DataResponseFactoryInterface;
use Yiisoft\Http\Header;
use Yiisoft\Router\CurrentRoute;
use Yiisoft\Yii\Debug\Api\Debug\Exception\NotFoundException;
use Yiisoft\Yii\Debug\Api\Debug\Exception\PackageNotInstalledException;
Expand All @@ -21,7 +23,6 @@
use Yiisoft\Yii\Debug\Api\ServerSentEventsStream;
use Yiisoft\Yii\Debug\Storage\StorageInterface;
use Yiisoft\Yii\View\ViewRenderer;
use OpenApi\Attributes as OA;

/**
* Debug controller provides endpoints that expose information about requests processed that debugger collected.
Expand Down Expand Up @@ -323,11 +324,11 @@
$retries = 0;

return $responseFactory->createResponse()
->withHeader('Content-Type', 'text/event-stream')
->withHeader('Cache-Control', 'no-cache')
->withHeader('Connection', 'keep-alive')
->withHeader(Header::CONTENT_TYPE, 'text/event-stream')
->withHeader(Header::CACHE_CONTROL, 'no-cache')
->withHeader(Header::CONNECTION, 'keep-alive')

Check warning on line 329 in src/Debug/Controller/DebugController.php

View check run for this annotation

Codecov / codecov/patch

src/Debug/Controller/DebugController.php#L327-L329

Added lines #L327 - L329 were not covered by tests
->withBody(
new ServerSentEventsStream(function (array &$buffer) use (

Check failure on line 331 in src/Debug/Controller/DebugController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

InvalidArgument

src/Debug/Controller/DebugController.php:331:44: InvalidArgument: Argument 1 of Yiisoft\Yii\Debug\Api\ServerSentEventsStream::__construct expects Closure():Generator, but impure-Closure(array<array-key, mixed>):bool provided (see https://psalm.dev/004)

Check failure on line 331 in src/Debug/Controller/DebugController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

InvalidArgument

src/Debug/Controller/DebugController.php:331:44: InvalidArgument: Argument 1 of Yiisoft\Yii\Debug\Api\ServerSentEventsStream::__construct expects Closure():Generator, but impure-Closure(array<array-key, mixed>):bool provided (see https://psalm.dev/004)

Check failure on line 331 in src/Debug/Controller/DebugController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

InvalidArgument

src/Debug/Controller/DebugController.php:331:44: InvalidArgument: Argument 1 of Yiisoft\Yii\Debug\Api\ServerSentEventsStream::__construct expects Closure():Generator, but impure-Closure(array<array-key, mixed>):bool provided (see https://psalm.dev/004)
$compareFunction,
&$hash,
&$retries,
Expand Down
54 changes: 54 additions & 0 deletions src/Inspector/Controller/DebugServerController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Yii\Debug\Api\Inspector\Controller;

use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Yiisoft\Http\Header;
use Yiisoft\Yii\Debug\Api\ServerSentEventsStream;
use Yiisoft\Yii\Debug\DebugServer\Connection;

final class DebugServerController
{
public function stream(

Check warning on line 15 in src/Inspector/Controller/DebugServerController.php

View check run for this annotation

Codecov / codecov/patch

src/Inspector/Controller/DebugServerController.php#L15

Added line #L15 was not covered by tests
ResponseFactoryInterface $responseFactory
): ResponseInterface {
if (\function_exists('pcntl_signal')) {
\pcntl_signal(\SIGINT, static function (): never {
exit(1);
});

Check warning on line 21 in src/Inspector/Controller/DebugServerController.php

View check run for this annotation

Codecov / codecov/patch

src/Inspector/Controller/DebugServerController.php#L18-L21

Added lines #L18 - L21 were not covered by tests
}

$socket = Connection::create();

Check failure on line 24 in src/Inspector/Controller/DebugServerController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

UndefinedClass

src/Inspector/Controller/DebugServerController.php:24:19: UndefinedClass: Class, interface or enum named Yiisoft\Yii\Debug\DebugServer\Connection does not exist (see https://psalm.dev/019)

Check failure on line 24 in src/Inspector/Controller/DebugServerController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

UndefinedClass

src/Inspector/Controller/DebugServerController.php:24:19: UndefinedClass: Class, interface or enum named Yiisoft\Yii\Debug\DebugServer\Connection does not exist (see https://psalm.dev/019)

Check failure on line 24 in src/Inspector/Controller/DebugServerController.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

UndefinedClass

src/Inspector/Controller/DebugServerController.php:24:19: UndefinedClass: Class, interface or enum named Yiisoft\Yii\Debug\DebugServer\Connection does not exist (see https://psalm.dev/019)
$socket->bind();

Check warning on line 25 in src/Inspector/Controller/DebugServerController.php

View check run for this annotation

Codecov / codecov/patch

src/Inspector/Controller/DebugServerController.php#L24-L25

Added lines #L24 - L25 were not covered by tests

return $responseFactory->createResponse()
->withHeader(Header::CONTENT_TYPE, 'text/event-stream')
->withHeader(Header::CACHE_CONTROL, 'no-cache')
->withHeader(Header::CONNECTION, 'keep-alive')
->withBody(
new ServerSentEventsStream(function () use ($socket) {
foreach ($socket->read() as $message) {
switch ($message[0]) {
case Connection::TYPE_ERROR:
return '';
case Connection::TYPE_RELEASE:

Check warning on line 37 in src/Inspector/Controller/DebugServerController.php

View check run for this annotation

Codecov / codecov/patch

src/Inspector/Controller/DebugServerController.php#L27-L37

Added lines #L27 - L37 were not covered by tests
/**
* Break the loop if the client aborted the connection (closed the page)
*/
if (connection_aborted()) {
return '';

Check warning on line 42 in src/Inspector/Controller/DebugServerController.php

View check run for this annotation

Codecov / codecov/patch

src/Inspector/Controller/DebugServerController.php#L41-L42

Added lines #L41 - L42 were not covered by tests
}
break;
case Connection::TYPE_RESULT:

Check warning on line 45 in src/Inspector/Controller/DebugServerController.php

View check run for this annotation

Codecov / codecov/patch

src/Inspector/Controller/DebugServerController.php#L44-L45

Added lines #L44 - L45 were not covered by tests

yield $message[1];

Check warning on line 47 in src/Inspector/Controller/DebugServerController.php

View check run for this annotation

Codecov / codecov/patch

src/Inspector/Controller/DebugServerController.php#L47

Added line #L47 was not covered by tests
}
}
return '';
})
);

Check warning on line 52 in src/Inspector/Controller/DebugServerController.php

View check run for this annotation

Codecov / codecov/patch

src/Inspector/Controller/DebugServerController.php#L50-L52

Added lines #L50 - L52 were not covered by tests
}
}
29 changes: 14 additions & 15 deletions src/ServerSentEventsStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
namespace Yiisoft\Yii\Debug\Api;

use Closure;
use Generator;
use Psr\Http\Message\StreamInterface;

final class ServerSentEventsStream implements StreamInterface, \Stringable
{
public array $buffer = [];
private bool $eof = false;

/**
* @param Closure(): Generator $stream
*/
public function __construct(
private Closure $stream,
) {
Expand All @@ -27,9 +30,9 @@
$this->eof = true;
}

public function getSize(): int
public function getSize(): ?int

Check warning on line 33 in src/ServerSentEventsStream.php

View check run for this annotation

Codecov / codecov/patch

src/ServerSentEventsStream.php#L33

Added line #L33 was not covered by tests
{
return 0;
return null;

Check warning on line 35 in src/ServerSentEventsStream.php

View check run for this annotation

Codecov / codecov/patch

src/ServerSentEventsStream.php#L35

Added line #L35 was not covered by tests
}

public function tell(): int
Expand Down Expand Up @@ -77,24 +80,20 @@
*/
public function read(int $length): string
{
$continue = ($this->stream)($this->buffer);
foreach (($this->stream)($this) as $message) {

Check failure on line 83 in src/ServerSentEventsStream.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

TooManyArguments

src/ServerSentEventsStream.php:83:18: TooManyArguments: Too many arguments for - expecting 0 but saw 1 (see https://psalm.dev/026)

Check failure on line 83 in src/ServerSentEventsStream.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

TooManyArguments

src/ServerSentEventsStream.php:83:18: TooManyArguments: Too many arguments for - expecting 0 but saw 1 (see https://psalm.dev/026)

Check failure on line 83 in src/ServerSentEventsStream.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

TooManyArguments

src/ServerSentEventsStream.php:83:18: TooManyArguments: Too many arguments for - expecting 0 but saw 1 (see https://psalm.dev/026)
if (empty($message)) {
break;

Check warning on line 85 in src/ServerSentEventsStream.php

View check run for this annotation

Codecov / codecov/patch

src/ServerSentEventsStream.php#L83-L85

Added lines #L83 - L85 were not covered by tests
}

if (!$continue) {
$this->eof = true;
return sprintf("data: %s\n\n", $message);

Check warning on line 88 in src/ServerSentEventsStream.php

View check run for this annotation

Codecov / codecov/patch

src/ServerSentEventsStream.php#L88

Added line #L88 was not covered by tests
}

$output = '';
foreach ($this->buffer as $key => $value) {
unset($this->buffer[$key]);
$output .= sprintf("data: %s\n", $value);
}
$output .= "\n";
return $output;
$this->eof = true;
return '';

Check warning on line 91 in src/ServerSentEventsStream.php

View check run for this annotation

Codecov / codecov/patch

src/ServerSentEventsStream.php#L90-L91

Added lines #L90 - L91 were not covered by tests
}

public function getContents(): string
{
return $this->read(1024);
return $this->read(8_388_608); // 8MB

Check warning on line 96 in src/ServerSentEventsStream.php

View check run for this annotation

Codecov / codecov/patch

src/ServerSentEventsStream.php#L96

Added line #L96 was not covered by tests
}

public function getMetadata($key = null): array
Expand Down
Loading