feat(home): live updates via Mercure — server pushes device state to the PWA
CI / test (push) Has been cancelled
CI / test (push) Has been cancelled
Subscribe per-device with a Symfony Mercure hub: server publishes a fresh device payload after every poll (200/304/204), every PATCH, and every lock/unlock. The frontend opens one EventSource per device topic and splats inbound JSON straight into the devices store — same shape as GET /api/devices, so no envelope handling. Topic: https://pictureframe.edholm.me/devices/{id} Stack mirrors aqua-iq: - symfony/mercure-bundle + config/packages/mercure.yaml - App\Service\MercurePublisher (errors swallowed + logged; a flaky hub must not break a poll response) - App\Service\DeviceSerializer extracted as the single source of truth for the wire shape (REST + Mercure share it) - Frontend useDeviceMercure() composable: opens/closes EventSources to match the device list reactively, reconnects on hub-side closes - SpaController exposes MERCURE_PUBLIC_URL via window.__PF_MERCURE_URL__ Production compose adds a dunglas/mercure container with Traefik labels for pictureframe.edholm.me/.well-known/mercure (handled separately on the host since the file isn't in this repo). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,4 +13,5 @@ return [
|
||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||
DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
|
||||
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
|
||||
Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true],
|
||||
];
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
mercure:
|
||||
hubs:
|
||||
default:
|
||||
url: '%env(default::MERCURE_URL)%'
|
||||
public_url: '%env(default::MERCURE_PUBLIC_URL)%'
|
||||
jwt:
|
||||
secret: '%env(MERCURE_JWT_SECRET)%'
|
||||
publish: '*'
|
||||
Reference in New Issue
Block a user