ba9625d45d
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>
107 lines
3.1 KiB
JSON
107 lines
3.1 KiB
JSON
{
|
|
"type": "project",
|
|
"license": "proprietary",
|
|
"minimum-stability": "stable",
|
|
"prefer-stable": true,
|
|
"require": {
|
|
"php": ">=8.2",
|
|
"ext-ctype": "*",
|
|
"ext-iconv": "*",
|
|
"doctrine/doctrine-bundle": "^3.2",
|
|
"doctrine/doctrine-migrations-bundle": "^4.0",
|
|
"doctrine/orm": "^3.6",
|
|
"phpdocumentor/reflection-docblock": "^6.0",
|
|
"phpstan/phpdoc-parser": "^2.3",
|
|
"symfony/asset": "7.4.*",
|
|
"symfony/console": "7.4.*",
|
|
"symfony/doctrine-messenger": "7.4.*",
|
|
"symfony/dotenv": "7.4.*",
|
|
"symfony/expression-language": "7.4.*",
|
|
"symfony/flex": "^2",
|
|
"symfony/form": "7.4.*",
|
|
"symfony/framework-bundle": "7.4.*",
|
|
"symfony/http-client": "7.4.*",
|
|
"symfony/intl": "7.4.*",
|
|
"symfony/mailer": "7.4.*",
|
|
"symfony/mercure-bundle": "^0.4.2",
|
|
"symfony/messenger": "7.4.*",
|
|
"symfony/mime": "7.4.*",
|
|
"symfony/monolog-bundle": "^3.0|^4.0",
|
|
"symfony/notifier": "7.4.*",
|
|
"symfony/process": "7.4.*",
|
|
"symfony/property-access": "7.4.*",
|
|
"symfony/property-info": "7.4.*",
|
|
"symfony/runtime": "7.4.*",
|
|
"symfony/scheduler": "7.4.*",
|
|
"symfony/security-bundle": "7.4.*",
|
|
"symfony/serializer": "7.4.*",
|
|
"symfony/string": "7.4.*",
|
|
"symfony/translation": "7.4.*",
|
|
"symfony/twig-bundle": "7.4.*",
|
|
"symfony/validator": "7.4.*",
|
|
"symfony/web-link": "7.4.*",
|
|
"symfony/yaml": "7.4.*",
|
|
"twig/extra-bundle": "^2.12|^3.0",
|
|
"twig/twig": "^2.12|^3.0"
|
|
},
|
|
"config": {
|
|
"allow-plugins": {
|
|
"php-http/discovery": true,
|
|
"symfony/flex": true,
|
|
"symfony/runtime": true
|
|
},
|
|
"bump-after-update": true,
|
|
"sort-packages": true
|
|
},
|
|
"autoload": {
|
|
"psr-4": {
|
|
"App\\": "src/"
|
|
}
|
|
},
|
|
"autoload-dev": {
|
|
"psr-4": {
|
|
"App\\Tests\\": "tests/"
|
|
}
|
|
},
|
|
"replace": {
|
|
"symfony/polyfill-ctype": "*",
|
|
"symfony/polyfill-iconv": "*",
|
|
"symfony/polyfill-php72": "*",
|
|
"symfony/polyfill-php73": "*",
|
|
"symfony/polyfill-php74": "*",
|
|
"symfony/polyfill-php80": "*",
|
|
"symfony/polyfill-php81": "*",
|
|
"symfony/polyfill-php82": "*"
|
|
},
|
|
"scripts": {
|
|
"auto-scripts": {
|
|
"cache:clear": "symfony-cmd",
|
|
"assets:install %PUBLIC_DIR%": "symfony-cmd"
|
|
},
|
|
"post-install-cmd": [
|
|
"@auto-scripts"
|
|
],
|
|
"post-update-cmd": [
|
|
"@auto-scripts"
|
|
]
|
|
},
|
|
"conflict": {
|
|
"symfony/symfony": "*"
|
|
},
|
|
"extra": {
|
|
"symfony": {
|
|
"allow-contrib": false,
|
|
"require": "7.4.*"
|
|
}
|
|
},
|
|
"require-dev": {
|
|
"phpunit/phpunit": "^13.1",
|
|
"symfony/browser-kit": "7.4.*",
|
|
"symfony/css-selector": "7.4.*",
|
|
"symfony/debug-bundle": "7.4.*",
|
|
"symfony/maker-bundle": "^1.0",
|
|
"symfony/stopwatch": "7.4.*",
|
|
"symfony/web-profiler-bundle": "7.4.*"
|
|
}
|
|
}
|