Initial Commit
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# services/registry-augmentation
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
This module is a TypeScript `declare module` augmentation. It adds the
|
||||
`searchIndexes` slot to `@suaveplan/api-plugin`'s canonical
|
||||
`ServiceRegistry` interface so any consumer importing
|
||||
`@suaveplan/api-plugin-search` automatically sees
|
||||
`ctx.getService("searchIndexes")` resolve to
|
||||
`Map<string, SearchIndex> | undefined`. Without this augmentation the
|
||||
`getService` call would fail TypeScript compilation because the
|
||||
default `ServiceRegistry` is empty by design.
|
||||
|
||||
## Features
|
||||
|
||||
- Adds `searchIndexes: Map<string, SearchIndex>` to the augmented
|
||||
registry.
|
||||
- Re-declares the host-side `app: OpenAPIHono` slot owned by
|
||||
`@suaveplan/api` so the search plugin's `onInit` can resolve `app`
|
||||
with full typing even in isolated unit tests that do not import
|
||||
`@suaveplan/api`. TypeScript merges duplicate `declare module`
|
||||
declarations transparently.
|
||||
- Side-effect-only module — importing the package barrel applies the
|
||||
augmentation automatically; there is nothing to call.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import "@suaveplan/api-plugin-search"; // side-effect augmentation
|
||||
import type { PluginContext } from "@suaveplan/api-plugin";
|
||||
|
||||
function consume(ctx: PluginContext): void {
|
||||
const indexes = ctx.getService("searchIndexes");
|
||||
// indexes: Map<string, SearchIndex> | undefined
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Sibling plugins that operate on the search index map can mutate it
|
||||
safely once the search plugin has run — the map is a live reference,
|
||||
not a snapshot:
|
||||
|
||||
```ts
|
||||
declare module "@suaveplan/api-plugin/service-registry" {
|
||||
interface ServiceRegistry {
|
||||
analyticsCollector: { onIndexEvent(event: string): void };
|
||||
}
|
||||
}
|
||||
|
||||
async function onReady(ctx: PluginContext): Promise<void> {
|
||||
const indexes = ctx.getService("searchIndexes");
|
||||
if (indexes !== undefined) {
|
||||
// …operate on indexes…
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
This module has no public runtime exports — it augments the
|
||||
`ServiceRegistry` interface from
|
||||
`@suaveplan/api-plugin/service-registry`. After import the augmented
|
||||
interface carries:
|
||||
|
||||
| Slot | Type |
|
||||
|---|---|
|
||||
| `searchIndexes` | `Map<string, SearchIndex>` |
|
||||
| `app` | `OpenAPIHono` (re-declared from `@suaveplan/api`) |
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The module pattern (`declare module "@suaveplan/api-plugin/service-registry" {…}`)
|
||||
relies on TypeScript's declaration merging. Multiple packages
|
||||
augmenting the same interface union their fields automatically; no
|
||||
package owns the registry exclusively. The empty `export {}` at the
|
||||
bottom forces this file to be a module rather than a script so the
|
||||
`declare module` is a proper augmentation rather than ambient
|
||||
declaration.
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* ServiceRegistry module augmentation — declares the `searchIndexes`
|
||||
* slot on `@suaveplan/api-plugin/service-registry`'s `ServiceRegistry`
|
||||
* interface so downstream plugins typed against the augmented registry
|
||||
* see `ctx.getService("searchIndexes")` resolve to
|
||||
* `Map<string, SearchIndex> | undefined` without any cast.
|
||||
*
|
||||
* Importing this module for its side effects (which the package root
|
||||
* barrel does automatically) is sufficient — every consumer of
|
||||
* `@suaveplan/api-plugin-search` gets typed `searchIndexes` access.
|
||||
*
|
||||
* The host-side slot `app` is owned by `@suaveplan/api`'s own
|
||||
* registry-augmentation module. We re-declare it here as a
|
||||
* cumulative augmentation so the search plugin's `onInit(ctx)` can
|
||||
* resolve it with full typing even when the consumer has not
|
||||
* explicitly imported `@suaveplan/api`. TypeScript merges duplicate
|
||||
* declarations.
|
||||
*/
|
||||
import type { OpenAPIHono } from "@hono/zod-openapi";
|
||||
import type { SearchIndex } from "../types/types.js";
|
||||
|
||||
declare module "@suaveplan/api-plugin/service-registry" {
|
||||
interface ServiceRegistry {
|
||||
searchIndexes: Map<string, SearchIndex>;
|
||||
app: OpenAPIHono;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user