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,83 @@
# EcsError & ECS_CODES
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`EcsError` is the typed error class for every failure mode raised by `@suaveplan/ecs`. It extends `SuaveplanError` from `@suaveplan/error`, which means every thrown error carries a stable, fully-qualified `code` string and a structured `context` object documenting the inputs at the failure site. Callers can discriminate failures from this package either by `instanceof EcsError` or by inspecting `error.code`.
`ECS_CODES` is the canonical registry of every code this package raises. The registry is generated through `defineCodes("ECS", [...])` from `@suaveplan/error`, which fully-qualifies the string literals (e.g., `"ECS.ENTITY_NOT_ALIVE"`) and exposes them as a frozen object.
## Features
- Stable, fully-qualified codes — `ECS.ENTITY_NOT_ALIVE`, `ECS.COMPONENT_NOT_REGISTERED`, `ECS.COMPONENT_NAME_CONFLICT`, `ECS.COMPONENT_LIMIT_REACHED`, `ECS.COMPONENT_VALIDATION_FAILED`, `ECS.SYSTEM_NAME_CONFLICT`, `ECS.SNAPSHOT_INVALID`.
- Every code is exercised by `src/errors/ecs-error.test.ts` from a real production code path — registry-to-throw-site coverage is a test invariant.
- Structured `context` field on every error (`{ entity }`, `{ name }`, `{ issues }`, etc.) so the wire-redacted error envelope remains useful for debugging.
- Cause chain preserved through `SuaveplanError`'s base support.
- Code type `EcsCode` is a literal union narrowable in `switch` statements.
## Usage: Basic Example
```ts
import { createWorld, defineComponent, ECS_CODES, EcsError } from "@suaveplan/ecs";
const Position = defineComponent("Position", { x: 0, y: 0 });
const world = createWorld();
const entity = world.spawn();
world.despawn(entity);
try {
world.addComponent(entity, Position);
} catch (err) {
if (err instanceof EcsError && err.code === ECS_CODES.ENTITY_NOT_ALIVE) {
console.error("entity was already despawned");
}
}
```
## Usage: Advanced Example
```ts
import { ECS_CODES, EcsError } from "@suaveplan/ecs";
function isRetryable(err: unknown): boolean {
if (!(err instanceof EcsError)) return false;
switch (err.code) {
case ECS_CODES.ENTITY_NOT_ALIVE:
case ECS_CODES.SNAPSHOT_INVALID:
return false;
case ECS_CODES.COMPONENT_VALIDATION_FAILED:
return false;
case ECS_CODES.COMPONENT_LIMIT_REACHED:
case ECS_CODES.COMPONENT_NAME_CONFLICT:
case ECS_CODES.COMPONENT_NOT_REGISTERED:
case ECS_CODES.SYSTEM_NAME_CONFLICT:
return false;
default:
return false;
}
}
```
## API Reference
| Symbol | Description |
|---|---|
| `EcsError` | `SuaveplanError`-extending class. Constructor: `new EcsError(code, messageKey, options?)`. |
| `EcsCode` | Type union over every registered code string. |
| `ECS_CODES` | Frozen registry returned by `defineCodes`. |
| `ECS_CODES.ENTITY_NOT_ALIVE` | Thrown from `addComponent` / `removeComponent` / `setComponent` for despawned entities. |
| `ECS_CODES.COMPONENT_NOT_REGISTERED` | `registry.getId(schema)` on an unknown schema. |
| `ECS_CODES.COMPONENT_NAME_CONFLICT` | Two distinct schemas sharing a `name`. |
| `ECS_CODES.COMPONENT_LIMIT_REACHED` | `register` past `maxComponents`. |
| `ECS_CODES.COMPONENT_VALIDATION_FAILED` | Zod validator rejected merged component data. |
| `ECS_CODES.SYSTEM_NAME_CONFLICT` | `addSystem` with a name already registered. |
| `ECS_CODES.SNAPSHOT_INVALID` | `restore` payload failed `WorldSnapshotSchema`. |
## Implementation Notes
- Codes are namespaced under `ECS.` so cross-package error log aggregation can filter by the `ECS.*` prefix.
- `EcsError` does not override `Error.prototype.toJSON` — `SuaveplanError` already exposes `toWire` / `toSpanEvent` for serialisation, and we don't extend the contract.
- The test suite enumerates `Object.values(ECS_CODES)` and triggers every code through a production call. If a new code is added without a real throw site, the test will fail — this is the registered-but-unthrown drift guard required by the spec-conformance checklist (`AGENTS.md` §13).