v0.3.0
Server-side plugin API. Resonate stays a product-agnostic Pusher relay, but a host application can now load ServerPlugin classes into the server process to intercept messages, observe the connection lifecycle, and run periodic ticks on the event loop. Ordinary Pusher traffic is unaffected: when every plugin returns Relay, routing is byte-identical to before.
Added
Webpatser\Resonate\Pluginsnamespace:ServerPluginmarker contract plus theMessageInterceptor,ConnectionLifecycle, andTickSchedulercapability interfaces.MessageDispositionenum (Handled/Rejected/Relay) returned by interceptors.PluginManager- capability-indexed registry; every fan-out call is exception-isolated so a plugin error cannot break the core.PluginContext- the API handed to plugins at boot:sendTo(),broadcast()(scaling-aware),terminate(),connectionsOn(), plusapplication()/applications().- Per-connection plugin state bag on the
Connectioncontract:setState(),state(),hasState(),forgetState(). - New config key
reverb.servers.reverb.plugins, an array ofServerPluginclass names resolved through the container. Scheduler(Webpatser\Resonate\Scheduling\Scheduler) - a thin layer over the Revolt event loop. Every task runs inside a fiber and is exception-isolated, named for logging, and cancellable.
Changed
Server::message()runs the interceptor chain after validation and before thepusher:/client-*split;Server::open()/close()andEventHandler::afterSubscribe()fire the lifecycle hooks.- A message a plugin marks
HandledorRejectedno longer fires theMessageReceivedevent or logsMessage Handled; both are now scoped to traffic the core actually routed (Relay). StartServerregisters all periodic work through theSchedulerinstead of bareEventLoop::repeatcalls, so every task is fiber-wrapped and exception-isolated. Periodic tasks are cancelled when the server begins to drain or stop.
Docs
- New
docs/plugins.md- a full setup walkthrough with a worked plugin implementing all three capabilities.
Suite grows to 313 tests.