Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
# `schemas/schemas.ts` — Zod options schema
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
This module owns the runtime validation surface for `@suaveplan/emblem-solver`.
It exposes `ConvertOptionsSchema`, a Zod schema that mirrors the static
`ConvertOptions` interface, applies sensible defaults, and rejects unknown
keys. `convert()` runs every caller-supplied options object through
`safeParse` so typos or out-of-range values fail loudly with
`EmblemSolverError(INVALID_OPTIONS)` rather than silently degrading the
solver.
## Features
- `layerOrder` defaults to `"auto"` and is validated as a closed enum over
the five supported strategies.
- `maxPermutations` defaults to `40320 = 8!` — the threshold beyond which
exhaustive permutation search is abandoned in favour of heuristics +
random sampling. The schema enforces `int().min(1)` so a zero or negative
value is rejected at the boundary.
- `rng` is an optional `() => number` validated with `z.custom<…>()`. It is
the only injection point for the package — supplying it makes the
heuristic + sampling path fully deterministic.
- `.strict()` rejects unknown keys, so misspelled options never silently
succeed.
## Usage: Basic
```ts
import { ConvertOptionsSchema } from "@suaveplan/emblem-solver/schemas";
const parsed = ConvertOptionsSchema.parse({ layerOrder: "area-desc" });
parsed.maxPermutations; // 40320 (default applied)
```
## Usage: Advanced
```ts
import { ConvertOptionsSchema } from "@suaveplan/emblem-solver/schemas";
import { EMBLEM_SOLVER_CODES, EmblemSolverError } from
"@suaveplan/emblem-solver/errors";
function safeOptions(raw: unknown) {
const r = ConvertOptionsSchema.safeParse(raw);
if (!r.success) {
throw new EmblemSolverError(
EMBLEM_SOLVER_CODES.INVALID_OPTIONS,
`bad options: ${r.error.issues
.map((i) => `${i.path.join(".")}: ${i.message}`)
.join("; ")}`
);
}
return r.data;
}
```
## API Reference
| Symbol | Kind | Description |
|---|---|---|
| `ConvertOptionsSchema` | `z.ZodObject` | Strict schema for `ConvertOptions` |
| `ConvertOptionsParsed` | type | Post-defaults shape of the parsed result |
## Implementation Notes
The schema lives in its own module so the rest of the package does not pay
the Zod cost at import time when consumers do not need validation (e.g.
hot-loop callers that constructed options at startup). `convert()` always
runs through this schema, but downstream tooling can call
`ConvertOptionsSchema.parse` ahead of time and pass the parsed result into
its own caching layer. We use `z.custom<() => number>` rather than
`z.function()` because Zod 4 deprecated runtime function validation in
favour of a custom predicate; this matches the catalog `zod ^4.x`. The
`rng` field stays optional (rather than defaulting to `Math.random`) so the
test harness can detect whether a caller injected a deterministic source.