jeffgreco13/laravel-wave
Laravel Wave offers an idiomatic wrapper around the Wave API, handling authentication, GraphQL queries, configuration, and service bindings so you can pull invoices, customers, and products into your Laravel app with clean, familiar syntax.
The v2.0.0 release is a major version bump with only a compare link in the changelog, so treat the upgrade as an unknown-risk change until you've read the diff between v1.2.0...v2.0.0 on GitHub.
Start here, in this order:
composer.json. With no release notes, the diff is the release note. Look specifically at the composer.json constraints (PHP/Laravel/Illuminate versions), any renamed/removed classes, changed method signatures, and anything under src/ that touches config keys or published assets.composer require jeffgreco13/laravel-wave:^2.0 --with-all-dependencies
Use --with-all-dependencies — a major bump in a broadcasting-adjacent package frequently drags illuminate/* constraints with it.php artisan vendor:publish --provider="Jeffgreco13\Wave\WaveServiceProvider" --tag=wave-config --force
git diff config/wave.php
If a migration or asset tag exists, publish those separately and review before running php artisan migrate.php artisan config:clear && php artisan cache:clear && php artisan queue:restart
queue:restart matters most — workers hold the old package code in memory and will keep running v1.2.0 logic long after you've upgraded.First use case: wire up a single, low-risk broadcast end-to-end (one model event → one subscribed client) on a staging environment before migrating any production channel. That gives you a working baseline to bisect against if the major version changed serialization, channel naming, or the client-side contract.
Upgrade-in-isolation pattern. Because v2.0.0 ships without notes, do the upgrade on a branch with a single test that exercises the package's core path. If that test passes, the rest of your usage is likely fine; if it fails, the diff narrows the cause fast.
Treat the package as an edge, not a core. Keep package calls behind a thin application-level wrapper (a service class or a small number of dedicated events/jobs) rather than sprinkling them through controllers and models. On a major bump with an opaque changelog, having one seam to fix beats grepping for facade calls across the codebase.
Broadcast through the queue by default. Use queued broadcasting for anything user-facing-but-not-instant, and reserve synchronous broadcasting for cases where ordering with the HTTP response actually matters. Configure BROADCAST_CONNECTION explicitly per environment — log locally, a real driver in staging/prod — so a missing driver doesn't silently no-op in production.
Channel authorization lives in your app. Keep private/presence channel callbacks in routes/channels.php alongside everything else, and write a test per channel. This is the most common place a major version quietly breaks you: if v2 changed how the authenticated user is resolved or what the callback receives, it will surface here rather than in the broadcast itself.
Test at the boundary, not the internals.
Event::fake([OrderShipped::class]);
// ... act ...
Event::assertDispatched(OrderShipped::class, fn ($e) => $e->order->is($order));
And for the transport layer, fake the broadcast rather than opening sockets in CI. Keep one slow, real integration test (staging only) that proves the wire protocol still works after the upgrade — that's the part fakes can't cover.
Version-pin in a monorepo / multi-app setup. If several applications share this package, pin ^2.0 and upgrade them together; a mixed fleet where the client contract differs between apps is the worst outcome of an undocumented major release.
UPGRADE.md, a CHANGELOG.md in the repo, and any diff in published config keys — a renamed config key with a default fallback will fail silently rather than loudly.config:cache was built pre-upgrade, and removed keys can throw on boot. Always config:clear before and config:cache after.php artisan queue:restart, php artisan octane:reload, and restart the broadcast server in the same deploy step.max_execution_time raised, output buffering and compression disabled, and a proxy that doesn't buffer responses. Symptom: the app "works" until enough users connect, then everything stalls.TrustProxies config produces wrong scheme/host in generated URLs and breaks client connections in ways that look like package bugs.Event::fake / logs) → does it reach the queue (failed jobs table, Horizon) → does the driver accept it (broadcast driver logs) → does the client receive it (browser network tab). Skipping to the client is the usual time sink.failed_jobs after the first production deploy on v2. A serialization change between major versions often surfaces as a job that throws only for certain payloads.1.2.0 in composer.lock, keep the previous published config in git, and confirm the v2 migrations (if any) are reversible before running them in production.How can I help you explore Laravel packages today?