services & inject
A service is a cross-cutting dependency — an API client, an analytics tracker, a
logger. Services are acquired with inject service.
inject service analyticsThe inject keyword always takes a kind qualifier — inject store or
inject service. A bare inject X is an error (SVC015): the qualifier names what
you’re acquiring.
Declaring a service
Section titled “Declaring a service”export service AnalyticsService { action track(event: string, props?: Record<string, unknown>) { // …send the event }}import { ServiceRegistry, createServiceInstance } from "@reactra/service"
export const AnalyticsService = { name: "AnalyticsService", factory: () => createServiceInstance(() => { const track = (event: string, props?: Record<string, unknown>) => { // …send the event } return { track } }),}
if (import.meta.hot) { import.meta.hot.accept((newMod) => { if (!newMod) return ServiceRegistry.replace(newMod.AnalyticsService) })}Services are registered at boot via configureServices (the generated manifest wires
this up). Unlike stores, services don’t auto-register — you provide their
implementation explicitly, which makes them straightforward to swap in tests.
Why DI
Section titled “Why DI”Because the implementation is injected, you can provide a fake in a test without touching the component:
inject service analytics // real in the app, a stub in testsaction save() { analytics.track("saved") }This keeps components testable and side-effects explicit.
Next: routing.