astro-dx
@astro-dx/core · Services

Services

Singleton classes with register/inject. Share reactive state across any island with explicit dependencies.

The two cards below are completely independent Astro islands. Component A mutates the service, Component B receives derived state from the same instance.
Component A — manages service state
0
Component B — receives from service
Double: 0

Code — manager component

typescript
import { inject } from "@astro-dx/core";
import { getElement } from "@astro-dx/dom";
import { onClick } from "@astro-dx/events";
import { CounterServiceClass } from "../../services/counter.service";

const counter = inject(CounterServiceClass);

getElement("#count-value").text(counter.count);

onClick("#btn-inc", () => counter.increment());
onClick("#btn-dec", () => counter.decrement());
onClick("#btn-reset", () => counter.reset());

Code — receiver component

typescript
import { inject } from "@astro-dx/core";
import { getElement } from "@astro-dx/dom";
import { CounterServiceClass } from "../../services/counter.service";

const counter = inject(CounterServiceClass);

getElement("#double-value").text(counter.double);

Cross-island list with shared service

This pair of islands also shares one service instance via inject().

Island A — Add to cart
Keyboard Mouse Monitor Headphones
Island B — Cart summary
Total items 0
    Clear cart

    Code example

    typescript
    // services/index.ts (loaded once from BaseLayout)
    import { register } from "@astro-dx/core";
    import { CounterServiceClass } from "../../services/counter.service";
    import { ShopServiceClass } from "../../services/shop.service";
    
    register([CounterServiceClass, ShopServiceClass]);
    
    // Any island/component
    import { inject } from "@astro-dx/core";
    
    const cart = inject(ShopServiceClass);
    cart.addToCart({ id: "k-1", name: "Keyboard", price: 99 });