From d75eb6a85d726f83c4cc69a1bc7a0357f31ffba0 Mon Sep 17 00:00:00 2001 From: Florent Morselli Date: Mon, 22 Apr 2024 20:35:15 +0200 Subject: [PATCH] Add event dispatching to manifest compilation This update introduces event dispatching in the manifest compilation process. PreManifestCompileEvent and PostManifestCompileEvent have been added, which are dispatched before and after the compilation respectively. The modification enhances the flexibility and extensibility of the manifest compilation process by allowing custom actions just before or after compilation. --- src/Event/NullEventDispatcher.php | 15 +++++++++++++++ src/Event/PostManifestCompileEvent.php | 16 ++++++++++++++++ src/Event/PreManifestCompileEvent.php | 15 +++++++++++++++ src/Service/ServiceWorkerCompiler.php | 2 ++ .../ManifestCompileEventListener.php | 16 ++++++++++++++-- src/Subscriber/PwaDevServerSubscriber.php | 19 ++++++++++++++++--- 6 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 src/Event/NullEventDispatcher.php create mode 100644 src/Event/PostManifestCompileEvent.php create mode 100644 src/Event/PreManifestCompileEvent.php diff --git a/src/Event/NullEventDispatcher.php b/src/Event/NullEventDispatcher.php new file mode 100644 index 0000000..c33d850 --- /dev/null +++ b/src/Event/NullEventDispatcher.php @@ -0,0 +1,15 @@ +dispatcher = $dispatcher ?? new NullEventDispatcher(); $this->manifestPublicUrl = '/' . trim($manifestPublicUrl, '/'); $options = [ AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES => true, @@ -55,7 +63,11 @@ public function __invoke(PreAssetsCompileEvent $event): void if (! $this->manifestEnabled) { return; } - $data = $this->serializer->serialize($this->manifest, 'json', $this->jsonOptions); - $this->assetsFilesystem->write($this->manifestPublicUrl, $data); + $manifest = clone $this->manifest; + $this->dispatcher->dispatch(new PreManifestCompileEvent($manifest)); + $data = $this->serializer->serialize($manifest, 'json', $this->jsonOptions); + $postEvent = new PostManifestCompileEvent($manifest, $data); + $this->dispatcher->dispatch($postEvent); + $this->assetsFilesystem->write($this->manifestPublicUrl, $postEvent->data); } } diff --git a/src/Subscriber/PwaDevServerSubscriber.php b/src/Subscriber/PwaDevServerSubscriber.php index 74e7294..0083454 100644 --- a/src/Subscriber/PwaDevServerSubscriber.php +++ b/src/Subscriber/PwaDevServerSubscriber.php @@ -4,8 +4,12 @@ namespace SpomkyLabs\PwaBundle\Subscriber; +use Psr\EventDispatcher\EventDispatcherInterface; use SpomkyLabs\PwaBundle\Dto\Manifest; use SpomkyLabs\PwaBundle\Dto\ServiceWorker; +use SpomkyLabs\PwaBundle\Event\NullEventDispatcher; +use SpomkyLabs\PwaBundle\Event\PostManifestCompileEvent; +use SpomkyLabs\PwaBundle\Event\PreManifestCompileEvent; use SpomkyLabs\PwaBundle\Service\ServiceWorkerCompiler; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Attribute\Autowire; @@ -31,6 +35,8 @@ final readonly class PwaDevServerSubscriber implements EventSubscriberInterface { + private EventDispatcherInterface $dispatcher; + private string $manifestPublicUrl; private null|string $serviceWorkerPublicUrl; @@ -55,7 +61,9 @@ public function __construct( private null|Profiler $profiler, #[Autowire('%kernel.debug%')] bool $debug, + null|EventDispatcherInterface $dispatcher = null, ) { + $this->dispatcher = $dispatcher ?? new NullEventDispatcher(); $this->manifestPublicUrl = '/' . trim($manifestPublicUrl, '/'); $serviceWorkerPublicUrl = $serviceWorker->dest; $this->serviceWorkerPublicUrl = '/' . trim($serviceWorkerPublicUrl, '/'); @@ -128,12 +136,17 @@ public static function getSubscribedEvents(): array private function serveManifest(RequestEvent $event): void { $this->profiler?->disable(); - $body = $this->serializer->serialize($this->manifest, 'json', $this->jsonOptions); - $response = new Response($body, Response::HTTP_OK, [ + $manifest = clone $this->manifest; + $this->dispatcher->dispatch(new PreManifestCompileEvent($manifest)); + $data = $this->serializer->serialize($manifest, 'json', $this->jsonOptions); + $postEvent = new PostManifestCompileEvent($manifest, $data); + $this->dispatcher->dispatch($postEvent); + + $response = new Response($data, Response::HTTP_OK, [ 'Cache-Control' => 'public, max-age=604800, immutable', 'Content-Type' => 'application/manifest+json', 'X-Manifest-Dev' => true, - 'Etag' => hash('xxh128', $body), + 'Etag' => hash('xxh128', $data), ]); $event->setResponse($response);