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,61 @@
# migration-executor
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`MigrationExecutor` takes a `MigrationPlan` and actually runs each migration in the specified direction, recording results in the store, emitting lifecycle events, and surfacing structured errors. It is the only component in the migration package that performs database writes. Separating execution from planning makes it easy to test each in isolation and to slot in different execution strategies (e.g. transactional, concurrent) without changing the planner logic.
## Features
- Runs `toApply` (direction `up`) or `toRollback` (direction `down`) from the plan.
- AbortSignal cancellation between each migration step.
- Checksum validation before applying already-recorded migrations.
- Dry-run mode: records which migrations would run without executing SQL.
- Event emission: `migration:plan`, `migration:before`, `migration:after`, `migration:failed`.
- Wraps all thrown errors in `MigrationError(MIGRATION.FAILED)` unless already a `MigrationError`.
## Usage: Basic Example
```ts
import { MigrationExecutor } from "@suaveplan/migration";
const executor = new MigrationExecutor({ store, context, dryRun: false });
const result = await executor.execute(plan, "up");
```
## Usage: Advanced Example
```ts
import { MigrationExecutor } from "@suaveplan/migration";
import { EventBus } from "@suaveplan/events";
const events = new EventBus<MigrationEventMap>();
events.on("migration:after", ({ migration, durationMs }) => {
console.log(`${migration.id} applied in ${durationMs}ms`);
});
const executor = new MigrationExecutor({ store, context, events });
const result = await executor.execute(plan, "up", { signal });
```
## API Reference
### `class MigrationExecutor`
**Constructor**: `(options: ExecutorOptions, clock?: Clock)`
- `options.store` — migration store adapter for recording results.
- `options.context` — migration context injected into each migration function.
- `options.events?` — optional event bus for lifecycle events.
- `options.dryRun?` — if `true`, collects applied IDs without running SQL (default `false`).
- `options.checksumValidation?` — if `true`, validates checksums on up-direction runs (default `true`).
### `execute(plan, direction, runOptions?): Promise<MigrationResult>`
Returns `{ applied, skipped, failed, direction, dryRun }`. Throws `MigrationError` on abort, checksum mismatch, or execution failure.
## Implementation Notes
Checksum validation runs only for `up` migrations that already have a ledger record with a checksum — it does not block the first application. The `down` direction requires `migration.down` to be defined; if absent, a `MIGRATION.NOT_FOUND` error is thrown.