Files
skills/docs/networking/network/service-discovery/README.md
2026-05-29 08:20:56 +01:00

96 lines
5.6 KiB
Markdown

# @suaveplan/service-discovery - Universal service discovery primitives: ServiceRegistry with TTL/expiry, query, AbortSignal-aware watch, optional storage persistence and EventBusLike integration. Shared foundation for every network-discovery-* plugin.
## Summary
Universal service-registry primitives. Provides the shared
`ServiceDescriptor`, `ServiceQuery`, `RegistryEvent`, and `ServiceRegistry`
contract consumed by every Wave-2 `network-discovery-*` plugin.
<!-- begin:auto-docs -->
## Documentation tree
- [service-registry](./src/core/service-registry/service-registry.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [service-registry](./src/core/service-registry/service-registry.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
<!-- end:auto-docs --> - [service-registry](./src/core/service-registry/service-registry.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [service-registry](./src/core/service-registry/service-registry.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [service-registry](./src/core/service-registry/service-registry.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [service-registry](./src/core/service-registry/service-registry.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ - [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_ - [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ - [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_
## Install
```bash
bun add @suaveplan/service-discovery
```
## Basic usage
```ts
import { ServiceRegistry } from "@suaveplan/service-discovery";
const registry = new ServiceRegistry({ ttlMs: 30_000 });
registry.register({
id: "api-1",
name: "api",
address: "10.0.0.1:8080",
status: "healthy",
region: "us-east-1",
tags: ["v1"],
});
const healthy = registry.query({ name: "api", status: "healthy" });
```
## Advanced usage: watch + bus + persistence
```ts
import { ServiceRegistry } from "@suaveplan/service-discovery";
import type { EventBusLike } from "@suaveplan/types";
declare const bus: EventBusLike<{
"service:registered": import("@suaveplan/service-discovery").ServiceDescriptor;
"service:deregistered": import("@suaveplan/service-discovery").ServiceDescriptor;
"service:expired": import("@suaveplan/service-discovery").ServiceDescriptor;
}>;
declare const storage: import("@suaveplan/service-discovery").ServiceRegistryStorageLike;
const registry = new ServiceRegistry({
ttlMs: 30_000,
maxServices: 5_000,
bus,
storage,
persistKey: "service-registry:v1",
});
await registry.load();
const ac = new AbortController();
(async () => {
for await (const ev of registry.watch({ name: "api" }, ac.signal)) {
console.log(ev.type, ev.service.id);
}
})();
// later:
await registry.flush();
ac.abort();
registry.dispose();
```
## What ships
- `ServiceRegistry` — in-memory store with TTL expiry, query, AbortSignal-
aware `watch()` async iterator, optional persistent backing, optional
`EventBusLike` fan-out.
- Typed error class `SvcDiscError` + frozen `SVC_DISC_CODES` registry
(`DUPLICATE_REGISTRATION` / `QUERY_INVALID` / `REGISTRY_FULL` /
`INVALID_OPTIONS`).
- Zod schemas at every public boundary.
- OTel: `svc_disc.registrations_total{outcome}`, `svc_disc.queries_total`,
`svc_disc.query_duration_ms`, `svc_disc.active_services` gauge.
See each feature module's sibling `.md` for the full surface.