first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
# @suaveplan/api-plugin-search - Full-text search plugin for @suaveplan/api with TF-weighted relevance scoring, four built-in text analyzers (standard / simple / whitespace / keyword), facets, scalar+array filters, multi-key sort, highlighting, prefix autocomplete, 9 OpenAPI-typed Hono routes, 10 SEARCH.* error codes, and 5 OTel instruments. Server-tier — runs in Bun and Node.
Full-text search plugin for `@suaveplan/api`. Brings TF-weighted relevance
scoring, four built-in text analyzers (`standard`, `simple`, `whitespace`,
`keyword`), faceted aggregation, scalar/array filters, multi-key sort,
optional highlighting, prefix autocomplete suggestions, and a typed
`SearchAdapter` interface for future persistent backends. Server-tier — runs
in Bun and Node.
<!-- begin:auto-docs -->
## Documentation tree
- [analyzer](./src/analyzer/analyzer.md) — The analyzer module owns the text-analysis pipeline used by both the indexing path and the query path of `@suaveplan/ap…
- [analyzer](./src/analyzer/analyzer.md) — The analyzer module owns the text-analysis pipeline used by both the indexing path and the query path of `@suaveplan/ap…
- [error-codes](./src/error-codes/error-codes.md) — The error-codes module defines the stable registry of programmatic failure codes raised by `@suaveplan/api-plugin-searc…
- [error-codes](./src/error-codes/error-codes.md) — The error-codes module defines the stable registry of programmatic failure codes raised by `@suaveplan/api-plugin-searc…
- [otel](./src/otel/instruments.md) — The OTel instruments module exposes the canonical set of meters the search plugin records on every hot path. The bundle…
- [instruments](./src/otel/instruments.md) — The OTel instruments module exposes the canonical set of meters the search plugin records on every hot path. The bundle…
- [plugin](./src/plugin/plugin.md) — The plugin module exposes `createSearchPlugin`, the `@suaveplan/api-plugin`-shaped factory that the host `PluginRegistr…
- [plugin](./src/plugin/plugin.md) — The plugin module exposes `createSearchPlugin`, the `@suaveplan/api-plugin`-shaped factory that the host `PluginRegistr…
- [routes](./src/routes/build-routes.md) — The build-routes module constructs the `OpenAPIHono` instance that the plugin mounts under `routePrefix` (`/search` by…
- [build-routes](./src/routes/build-routes.md) — The build-routes module constructs the `OpenAPIHono` instance that the plugin mounts under `routePrefix` (`/search` by…
- [schemas](./src/schemas/schemas.md) — The schemas module owns the public Zod surface of `@suaveplan/api-plugin-search`. Every HTTP route in the package valid…
- [options](./src/schemas/options.md) — The options module defines the Zod schema for the input accepted by `createSearchPlugin(options?)`. The factory validat…
- [schemas](./src/schemas/schemas.md) — The schemas module owns the public Zod surface of `@suaveplan/api-plugin-search`. Every HTTP route in the package valid…
- [service](./src/service/service.md) — The service module is the in-memory search engine that powers `@suaveplan/api-plugin-search`. It owns index creation an…
- [service](./src/service/service.md) — The service module is the in-memory search engine that powers `@suaveplan/api-plugin-search`. It owns index creation an…
- [services](./src/services/registry-augmentation.md) — This module is a TypeScript `declare module` augmentation. It adds the `searchIndexes` slot to `@suaveplan/api-plugin`'…
- [registry-augmentation](./src/services/registry-augmentation.md) — This module is a TypeScript `declare module` augmentation. It adds the `searchIndexes` slot to `@suaveplan/api-plugin`'…
- [types](./src/types/types.md) — The types module owns the internal-shape contracts of the search plugin — the materialised `SearchIndex` held in memory…
- [types](./src/types/types.md) — The types module owns the internal-shape contracts of the search plugin — the materialised `SearchIndex` held in memory…
<!-- end:auto-docs -->
## Install
```bash
bun add @suaveplan/api-plugin-search
```
## Quick start
```ts
import { createApi } from "@suaveplan/api";
import { createSearchPlugin } from "@suaveplan/api-plugin-search";
const api = createApi({
plugins: [
createSearchPlugin({
routePrefix: "/search",
maxIndexes: 100,
maxDocumentsPerIndex: 100_000,
defaultAnalyzer: "standard",
}),
],
});
await api.start();
// POST /search/indexes → create index
// POST /search/indexes/:name/documents → index a document
// POST /search/query → run a search
// POST /search/suggest → prefix autocomplete
```
## Features
- **9 HTTP routes** with Zod-typed `@hono/zod-openapi` request/response
validation: `POST /query`, `POST /suggest`, `GET /indexes`,
`POST /indexes`, `GET /indexes/:name`, `DELETE /indexes/:name`,
`POST /indexes/:name/documents`, `POST /indexes/:name/bulk`,
`DELETE /indexes/:name/documents/:docId`.
- **TF × field-weight scoring** with deterministic ordering, plus
five-way sort (`relevance`, `date_asc`, `date_desc`, `alpha_asc`,
`alpha_desc`).
- **Four built-in analyzers** — `standard` (tokenise → stop-words →
stem), `simple` (tokenise only), `whitespace` (case-preserving), and
`keyword` (single-token) — plus public primitives (`tokenize`,
`removeStopWords`, `stem`) for custom analyzers.
- **Faceted aggregation** restricted to fields declared with
`facet: true`; counts reflect the filtered document set.
- **Scalar + array filters** through a single Zod schema so callers can
send `{ tag: "blog" }` or `{ tag: ["blog", "release"] }` with the
same field.
- **Optional highlighting** wrapping matching whole words in the
configured tag (`<mark>` by default).
- **Prefix autocomplete** via `suggest()` — ranks by occurrence count
across every indexed field.
- **10 `SEARCH.*` error codes** through `defineCodes` so callers can
branch on `error.code` with full type narrowing.
- **5 OTel instruments** under the `@suaveplan/api-plugin-search`
meter — counters for queries / indexes / docs / suggests and a
histogram for query duration.
- **`ServiceRegistry` augmentation** — `ctx.getService("searchIndexes")`
returns `Map<string, SearchIndex> | undefined` without a cast.
## Modules
- [`analyzer/analyzer`](./src/analyzer/analyzer.md)
- [`error-codes/error-codes`](./src/error-codes/error-codes.md)
- [`otel/instruments`](./src/otel/instruments.md)
- [`plugin/plugin`](./src/plugin/plugin.md)
- [`routes/build-routes`](./src/routes/build-routes.md)
- [`schemas/options`](./src/schemas/options.md)
- [`schemas/schemas`](./src/schemas/schemas.md)
- [`service/service`](./src/service/service.md)
- [`services/registry-augmentation`](./src/services/registry-augmentation.md)
- [`types/types`](./src/types/types.md)
## Status
`0.1.0` — first migration wave shipping` with full upstream
parity. Persistent backends (`SearchAdapter` implementations against
SurrealDB FTS / Typesense / Meilisearch), tenant scoping, auth gates,
rate limiting, and the enterprise-audit §4 enhancements (vector search,
synonyms, query DSL, saved searches, learning-to-rank) are tracked as
follow-up changes.