Skip to content

Commit

Permalink
Refactor event listeners and service workers
Browse files Browse the repository at this point in the history
The code has been refactored to simplify event listeners and service workers. Redundant event listeners have been removed and replaced with a single FileCompileEventListener. The logic for serving manifest files and service workers has been abstracted into a FileCompilerInterface, which is implemented by ServiceWorkerCompiler and ManifestCompiler. This results in more modular and coherent architecture.
  • Loading branch information
Spomky committed Apr 25, 2024
1 parent 1b4fabf commit a493124
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 313 deletions.
18 changes: 8 additions & 10 deletions src/Resources/config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
use SpomkyLabs\PwaBundle\ImageProcessor\GDImageProcessor;
use SpomkyLabs\PwaBundle\ImageProcessor\ImagickImageProcessor;
use SpomkyLabs\PwaBundle\MatchCallbackHandler\MatchCallbackHandlerInterface;
use SpomkyLabs\PwaBundle\Service\FileCompilerInterface;
use SpomkyLabs\PwaBundle\Service\ManifestBuilder;
use SpomkyLabs\PwaBundle\Service\ManifestCompiler;
use SpomkyLabs\PwaBundle\Service\ServiceWorkerBuilder;
use SpomkyLabs\PwaBundle\Service\ServiceWorkerCompiler;
use SpomkyLabs\PwaBundle\ServiceWorkerRule\ServiceWorkerRuleInterface;
use SpomkyLabs\PwaBundle\Subscriber\ManifestCompileEventListener;
use SpomkyLabs\PwaBundle\Subscriber\FileCompileEventListener;
use SpomkyLabs\PwaBundle\Subscriber\PwaDevServerSubscriber;
use SpomkyLabs\PwaBundle\Subscriber\ServiceWorkerCompileEventListener;
use SpomkyLabs\PwaBundle\Subscriber\WorkboxCompileEventListener;
use SpomkyLabs\PwaBundle\Twig\InstanceOfExtension;
use SpomkyLabs\PwaBundle\Twig\PwaExtension;
use SpomkyLabs\PwaBundle\Twig\PwaRuntime;
Expand All @@ -43,6 +43,8 @@
->autowire()
;

$container->instanceof(FileCompilerInterface::class)->tag('spomky_labs_pwa.compiler');

/*** Manifest ***/
$container->set(ManifestBuilder::class)
->args([
Expand All @@ -52,6 +54,7 @@
$container->set(Manifest::class)
->factory([service(ManifestBuilder::class), 'create'])
;
$container->set(ManifestCompiler::class);

/*** Service Worker ***/
$container->set(ServiceWorkerBuilder::class)
Expand All @@ -62,8 +65,7 @@
$container->set(ServiceWorker::class)
->factory([service(ServiceWorkerBuilder::class), 'create'])
;
$container->set(ServiceWorkerCompiler::class)
;
$container->set(ServiceWorkerCompiler::class);

/*** Commands ***/
if (class_exists(Client::class) && class_exists(WebDriverDimension::class) && class_exists(MimeTypes::class)) {
Expand Down Expand Up @@ -96,11 +98,7 @@
}

/*** Event Listeners and Subscribers ***/
$container->set(WorkboxCompileEventListener::class);
$container->set(ManifestCompileEventListener::class);
$container->set(ServiceWorkerCompileEventListener::class);
$container->set(ServiceWorkerCompiler::class);

$container->set(FileCompileEventListener::class);
$container->set(PwaDevServerSubscriber::class)
->args([
'$profiler' => service('profiler')
Expand Down
29 changes: 29 additions & 0 deletions src/Service/Data.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace SpomkyLabs\PwaBundle\Service;

/**
* @internal
*/
final readonly class Data
{
/**
* @param string[] $headers
*/
public function __construct(
public string $url,
public string $data,
public array $headers
){
}

/**
* @param array<string, string> $headers
*/
public static function create(string $url, string $data, array $headers = []): self
{
return new self($url, $data, $headers);
}
}
15 changes: 15 additions & 0 deletions src/Service/FileCompilerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace SpomkyLabs\PwaBundle\Service;

interface FileCompilerInterface
{
/**
* @return array<string>
*/
public function supportedPublicUrls(): array;

public function get(string $publicUrl): null|Data;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,49 @@

declare(strict_types=1);

namespace SpomkyLabs\PwaBundle\Subscriber;
namespace SpomkyLabs\PwaBundle\Service;

use Psr\EventDispatcher\EventDispatcherInterface;
use SpomkyLabs\PwaBundle\Dto\Manifest;
use SpomkyLabs\PwaBundle\Event\NullEventDispatcher;
use SpomkyLabs\PwaBundle\Event\PostManifestCompileEvent;
use SpomkyLabs\PwaBundle\Event\PreManifestCompileEvent;
use Symfony\Component\AssetMapper\Event\PreAssetsCompileEvent;
use Symfony\Component\AssetMapper\Path\PublicAssetsFilesystemInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\Serializer\Encoder\JsonEncode;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\TranslatableNormalizer;
use Symfony\Component\Serializer\SerializerInterface;
use function assert;
use function count;
use const JSON_PRETTY_PRINT;
use const JSON_THROW_ON_ERROR;
use const JSON_UNESCAPED_SLASHES;
use const JSON_UNESCAPED_UNICODE;

#[AsEventListener(PreAssetsCompileEvent::class)]
final readonly class ManifestCompileEventListener
final class ManifestCompiler implements FileCompilerInterface
{
private EventDispatcherInterface $dispatcher;
private readonly EventDispatcherInterface $dispatcher;

private string $manifestPublicUrl;
private readonly string $manifestPublicUrl;

private array $jsonOptions;
/**
* @var array<string, mixed>
*/
private readonly array $jsonOptions;

/**
* @param array<string> $locales
*/
public function __construct(
private SerializerInterface $serializer,
private Manifest $manifest,
private readonly SerializerInterface $serializer,
private readonly Manifest $manifest,
#[Autowire('%spomky_labs_pwa.manifest.public_url%')]
string $manifestPublicUrl,
#[Autowire('@asset_mapper.local_public_assets_filesystem')]
private PublicAssetsFilesystemInterface $assetsFilesystem,
#[Autowire('%kernel.debug%')]
bool $debug,
null|EventDispatcherInterface $dispatcher,
#[Autowire('%kernel.enabled_locales%')]
private array $locales,
private readonly array $locales,
) {
$this->dispatcher = $dispatcher ?? new NullEventDispatcher();
$this->manifestPublicUrl = '/' . trim($manifestPublicUrl, '/');
Expand All @@ -64,24 +60,46 @@ public function __construct(
$this->jsonOptions = $options;
}

public function __invoke(PreAssetsCompileEvent $event): void
/**
* @return array<string>
*/
public function supportedPublicUrls(): array
{
if (! $this->manifest->enabled) {
return;
if ($this->manifest->enabled === false) {
return [];
}

if ($this->locales === []) {
return [$this->manifestPublicUrl];
}
$manifest = clone $this->manifest;

if (count($this->locales) === 0 || ! str_contains($this->manifestPublicUrl, '{locale}')) {
$this->compileManifest($manifest, null);
} else {
foreach ($this->locales as $locale) {
$this->compileManifest($manifest, $locale);
return array_map(
fn (string $locale) => str_replace('{locale}', $locale, $this->manifestPublicUrl),
$this->locales
);
}

public function get(string $publicUrl): null|Data
{
if ($this->manifest->enabled === false) {
return null;
}
if ($this->locales === []) {
return $this->compileManifest(null);
}

foreach ($this->locales as $locale) {
if ($publicUrl === str_replace('{locale}', $locale, $this->manifestPublicUrl)) {
return $this->compileManifest($locale);
}
}

return null;
}

private function compileManifest(Manifest $manifest, null|string $locale): void
private function compileManifest(null|string $locale): Data
{
$manifest = clone $this->manifest;
$preEvent = new PreManifestCompileEvent($manifest);
$preEvent = $this->dispatcher->dispatch($preEvent);
assert($preEvent instanceof PreManifestCompileEvent);
Expand All @@ -98,6 +116,15 @@ private function compileManifest(Manifest $manifest, null|string $locale): void
$postEvent = $this->dispatcher->dispatch($postEvent);
assert($postEvent instanceof PostManifestCompileEvent);

$this->assetsFilesystem->write($manifestPublicUrl, $postEvent->data);
return Data::create(
$manifestPublicUrl,
$postEvent->data,
[

Check failure on line 122 in src/Service/ManifestCompiler.php

View workflow job for this annotation

GitHub Actions / 3️⃣ Static Analysis

Parameter #3 $headers of static method SpomkyLabs\PwaBundle\Service\Data::create() expects array<string, string>, array<string, string|true> given.
'Cache-Control' => 'public, max-age=604800, immutable',
'Content-Type' => 'application/manifest+json',
'X-Manifest-Dev' => true,
'Etag' => hash('xxh128', $data),
]
);
}
}
Loading

0 comments on commit a493124

Please sign in to comment.