Skip to content

Commit

Permalink
Better Service Worker (#57)
Browse files Browse the repository at this point in the history
Better Service Worker
  • Loading branch information
Spomky authored Feb 6, 2024
1 parent 5e704bd commit 58f53d7
Show file tree
Hide file tree
Showing 18 changed files with 257 additions and 162 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/coding-standards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
php-versions: ['8.2']
php-versions: ['8.3']
name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}

steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/rector_checkstyle.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
operating-system: [ ubuntu-latest ]
php-versions: ['8.2']
php-versions: ['8.3']
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/static-analyze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
php-versions: ['8.2']
php-versions: ['8.3']
name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}

steps:
Expand Down
62 changes: 31 additions & 31 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,6 @@ parameters:
count: 1
path: src/Command/CreateServiceWorkerCommand.php

-
message: "#^Parameter \\#1 \\$value of function count expects array\\|Countable, array\\|string given\\.$#"
count: 1
path: src/Command/CreateServiceWorkerCommand.php

-
message: "#^Parameter \\#2 \\$targetFile of method Symfony\\\\Component\\\\Filesystem\\\\Filesystem\\:\\:copy\\(\\) expects string, mixed given\\.$#"
count: 1
Expand Down Expand Up @@ -220,6 +215,11 @@ parameters:
count: 1
path: src/Dto/ScopeExtension.php

-
message: "#^Class SpomkyLabs\\\\PwaBundle\\\\Dto\\\\Screenshot has an uninitialized property \\$src\\. Give it default value or assign it in the constructor\\.$#"
count: 1
path: src/Dto/Screenshot.php

-
message: "#^Method SpomkyLabs\\\\PwaBundle\\\\Dto\\\\Screenshot\\:\\:getLabel\\(\\) should return string\\|Symfony\\\\Contracts\\\\Translation\\\\TranslatableInterface\\|null but returns array\\<string\\|Symfony\\\\Contracts\\\\Translation\\\\TranslatableInterface\\>\\|string\\|Symfony\\\\Contracts\\\\Translation\\\\TranslatableInterface\\|null\\.$#"
count: 1
Expand Down Expand Up @@ -325,11 +325,6 @@ parameters:
count: 1
path: src/Dto/Workbox.php

-
message: "#^Class SpomkyLabs\\\\PwaBundle\\\\Dto\\\\Workbox has an uninitialized property \\$precachingPlaceholder\\. Give it default value or assign it in the constructor\\.$#"
count: 1
path: src/Dto/Workbox.php

-
message: "#^Class SpomkyLabs\\\\PwaBundle\\\\Dto\\\\Workbox has an uninitialized property \\$standardRulesPlaceholder\\. Give it default value or assign it in the constructor\\.$#"
count: 1
Expand All @@ -345,11 +340,6 @@ parameters:
count: 1
path: src/Dto/Workbox.php

-
message: "#^Class SpomkyLabs\\\\PwaBundle\\\\Dto\\\\Workbox has an uninitialized property \\$warmCachePlaceholder\\. Give it default value or assign it in the constructor\\.$#"
count: 1
path: src/Dto/Workbox.php

-
message: "#^Class SpomkyLabs\\\\PwaBundle\\\\Dto\\\\Workbox has an uninitialized property \\$widgetsPlaceholder\\. Give it default value or assign it in the constructor\\.$#"
count: 1
Expand Down Expand Up @@ -390,6 +380,31 @@ parameters:
count: 1
path: src/ImageProcessor/GDImageProcessor.php

-
message: "#^Method SpomkyLabs\\\\PwaBundle\\\\Normalizer\\\\AssetNormalizer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/Normalizer/AssetNormalizer.php

-
message: "#^Method SpomkyLabs\\\\PwaBundle\\\\Normalizer\\\\AssetNormalizer\\:\\:normalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/Normalizer/AssetNormalizer.php

-
message: "#^Method SpomkyLabs\\\\PwaBundle\\\\Normalizer\\\\AssetNormalizer\\:\\:supportsDenormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/Normalizer/AssetNormalizer.php

-
message: "#^Method SpomkyLabs\\\\PwaBundle\\\\Normalizer\\\\AssetNormalizer\\:\\:supportsNormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/Normalizer/AssetNormalizer.php

-
message: "#^PHPDoc tag @return with type array\\<string, string\\> is incompatible with native type string\\.$#"
count: 1
path: src/Normalizer/AssetNormalizer.php

-
message: "#^Method SpomkyLabs\\\\PwaBundle\\\\Normalizer\\\\IconNormalizer\\:\\:normalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
Expand Down Expand Up @@ -420,21 +435,11 @@ parameters:
count: 1
path: src/Normalizer/ScreenshotNormalizer.php

-
message: "#^Parameter \\#1 \\$haystack of function str_starts_with expects string, string\\|null given\\.$#"
count: 1
path: src/Normalizer/ScreenshotNormalizer.php

-
message: "#^Parameter \\#1 \\$image of method SpomkyLabs\\\\PwaBundle\\\\ImageProcessor\\\\ImageProcessor\\:\\:getSizes\\(\\) expects string, string\\|false given\\.$#"
count: 1
path: src/Normalizer/ScreenshotNormalizer.php

-
message: "#^Parameter \\#1 \\$logicalPath of method Symfony\\\\Component\\\\AssetMapper\\\\AssetMapperInterface\\:\\:getAsset\\(\\) expects string, string\\|null given\\.$#"
count: 1
path: src/Normalizer/ScreenshotNormalizer.php

-
message: "#^Method SpomkyLabs\\\\PwaBundle\\\\Normalizer\\\\ServiceWorkerNormalizer\\:\\:normalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
Expand Down Expand Up @@ -478,9 +483,4 @@ parameters:
-
message: "#^Method SpomkyLabs\\\\PwaBundle\\\\Normalizer\\\\UrlNormalizer\\:\\:supportsNormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#"
count: 1
path: src/Normalizer/UrlNormalizer.php

-
message: "#^Parameter \\#1 \\$string of function mb_strlen expects string, string\\|null given\\.$#"
count: 1
path: src/Subscriber/PwaDevServerSubscriber.php
path: src/Normalizer/UrlNormalizer.php
36 changes: 19 additions & 17 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,6 @@ private function setupServiceWorker(ArrayNodeDefinition $node): void
)
->example('//STANDARD_RULES_PLACEHOLDER')
->end()
->scalarNode('precaching_placeholder')
->defaultValue('//PRECACHING_PLACEHOLDER')
->info(
'The placeholder for the precaching. Will be replaced by the assets and versions.'
)
->example('//PRECACHING_PLACEHOLDER')
->end()
->scalarNode('warm_cache_placeholder')
->defaultValue('//WARM_CACHE_URLS_PLACEHOLDER')
->info('The placeholder for the warm cache. Will be replaced by the URLs.')
->example('//WARM_CACHE_URLS_PLACEHOLDER')
->end()
->scalarNode('offline_fallback_placeholder')
->defaultValue('//OFFLINE_FALLBACK_PLACEHOLDER')
->info('The placeholder for the offline fallback. Will be replaced by the URL.')
Expand All @@ -154,12 +142,26 @@ private function setupServiceWorker(ArrayNodeDefinition $node): void
)
->example('//WIDGETS_PLACEHOLDER')
->end()
->append(
$this->getUrlNode(
'offline_fallback',
'The URL of the offline fallback. If not set, the offline fallback will be disabled.'
->append($this->getUrlNode('page_fallback', 'The URL of the offline page fallback.'))
->append($this->getUrlNode('image_fallback', 'The URL of the offline image fallback.'))
->append($this->getUrlNode('font_fallback', 'The URL of the offline font fallback.'))
->scalarNode('image_regex')
->defaultValue('/\.(ico|png|jpe?g|gif|svg|webp|bmp)$/')
->info('The regex to match the images.')
->example('/\.(ico|png|jpe?g|gif|svg|webp|bmp)$/')
->end()
->integerNode('max_image_cache_entries')
->defaultValue(60)
->info('The maximum number of entries in the image cache.')
->example([50, 100, 200])
->end()
->integerNode('network_timeout_seconds')
->defaultValue(3)
->info(
'The network timeout in seconds before cache is called (for warm cache URLs only).'
)
)
->example([1, 2, 5])
->end()
->arrayNode('warm_cache_urls')
->treatNullLike([])
->treatFalseLike([])
Expand Down
18 changes: 18 additions & 0 deletions src/Dto/Asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace SpomkyLabs\PwaBundle\Dto;

final class Asset
{
public function __construct(
public string $src
) {
}

public static function create(string $data): self
{
return new self($data);
}
}
2 changes: 1 addition & 1 deletion src/Dto/Icon.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

final class Icon
{
public string $src;
public Asset $src;

/**
* @var array<int>
Expand Down
2 changes: 1 addition & 1 deletion src/Dto/Screenshot.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ final class Screenshot
{
use TranslatableTrait;

public null|string $src = null;
public Asset $src;

public null|int $height = null;

Expand Down
2 changes: 1 addition & 1 deletion src/Dto/ServiceWorker.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ final class ServiceWorker
{
public bool $enabled;

public string $src;
public Asset $src;

public string $dest;

Expand Down
28 changes: 20 additions & 8 deletions src/Dto/Workbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,39 @@ final class Workbox
#[SerializedName('workbox_import_placeholder')]
public string $workboxImportPlaceholder;

#[SerializedName('warm_cache_placeholder')]
public string $warmCachePlaceholder;

#[SerializedName('standard_rules_placeholder')]
public string $standardRulesPlaceholder;

#[SerializedName('precaching_placeholder')]
public string $precachingPlaceholder;

#[SerializedName('offline_fallback_placeholder')]
public string $offlineFallbackPlaceholder;

#[SerializedName('widgets_placeholder')]
public string $widgetsPlaceholder;

#[SerializedName('offline_fallback')]
public null|Url $offlineFallback = null;
#[SerializedName('page_fallback')]
public null|Url $pageFallback = null;

#[SerializedName('image_fallback')]
public null|Url $imageFallback = null;

#[SerializedName('font_fallback')]
public null|Url $fontFallback = null;

/**
* @var array<Url>
*/
#[SerializedName('warm_cache_urls')]
public array $warmCacheUrls = [];

#[SerializedName('network_timeout_seconds')]
public int $networkTimeoutSeconds = 3;

#[SerializedName('max_image_cache_entries')]
public int $maxImageCacheEntries = 60;

#[SerializedName('image_regex')]
public string $imageRegex = '/\.(ico|png|jpe?g|gif|svg|webp|bmp)$/';

#[SerializedName('static_regex')]
public string $staticRegex = '/\.(css|js|json|xml|txt|woff2|ttf|eot|otf|map|webmanifest)$/';
}
70 changes: 70 additions & 0 deletions src/Normalizer/AssetNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

namespace SpomkyLabs\PwaBundle\Normalizer;

use SpomkyLabs\PwaBundle\Dto\Asset;
use Symfony\Component\AssetMapper\AssetMapperInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use function assert;
use function is_string;

final readonly class AssetNormalizer implements NormalizerInterface, DenormalizerInterface
{
public function __construct(
private AssetMapperInterface $assetMapper,
) {
}

/**
* @return array{src: string, sizes?: string, form_factor?: string, label?: string, platform?: string, format?: string}
*/
public function normalize(mixed $object, string $format = null, array $context = []): string
{
assert($object instanceof Asset);
$url = null;
dump($object);
if (! str_starts_with($object->src, '/')) {
$asset = $this->assetMapper->getAsset($object->src);
$url = $asset?->publicPath;
}
if ($url === null) {
$url = $object->src;
}

return $url;
}

public function denormalize(mixed $data, string $type, string $format = null, array $context = []): mixed
{
assert(is_string($data));

return Asset::create($data);
}

public function supportsNormalization(mixed $data, string $format = null, array $context = []): bool
{
return $data instanceof Asset;
}

public function supportsDenormalization(
mixed $data,
string $type,
string $format = null,
array $context = []
): bool {
return $type === Asset::class;
}

/**
* @return array<class-string, bool>
*/
public function getSupportedTypes(?string $format): array
{
return [
Asset::class => true,
];
}
}
15 changes: 5 additions & 10 deletions src/Normalizer/IconNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,14 @@ public function __construct(
public function normalize(mixed $object, string $format = null, array $context = []): array
{
assert($object instanceof Icon);
$url = null;
$asset = null;
if (! str_starts_with($object->src, '/')) {
$asset = $this->assetMapper->getAsset($object->src);
$url = $asset?->publicPath;
$format = null;
if (! str_starts_with($object->src->src, '/')) {
$asset = $this->assetMapper->getAsset($object->src->src);
$format = $this->getFormat($object, $asset);
}
if ($url === null) {
$url = $object->src;
}
$format = $this->getFormat($object, $asset);

$result = [
'src' => $url,
'src' => $object->src,
'sizes' => $object->getSizeList(),
'type' => $format,
'purpose' => $object->purpose,
Expand Down
Loading

0 comments on commit 58f53d7

Please sign in to comment.