Compare commits
3 Commits
main
...
8f94cc915c
| Author | SHA1 | Date | |
|---|---|---|---|
|
8f94cc915c
|
|||
|
3f114bb68d
|
|||
|
0846dbb758
|
@@ -4,10 +4,12 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- '**'
|
||||
|
||||
jobs:
|
||||
detect-version-change:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/main'
|
||||
outputs:
|
||||
version_changed: ${{ steps.check.outputs.version_changed }}
|
||||
steps:
|
||||
@@ -35,7 +37,7 @@ jobs:
|
||||
|
||||
changelog-only:
|
||||
needs: detect-version-change
|
||||
if: needs.detect-version-change.outputs.version_changed == 'false'
|
||||
if: github.ref != 'refs/heads/main' || needs.detect-version-change.outputs.version_changed == 'false'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -75,12 +77,12 @@ jobs:
|
||||
echo "No changes to commit"
|
||||
else
|
||||
git commit -m "chore(changelog): update unreleased changelog"
|
||||
git push origin main
|
||||
git push origin "${GITHUB_REF##refs/heads/}"
|
||||
fi
|
||||
|
||||
release:
|
||||
needs: detect-version-change
|
||||
if: needs.detect-version-change.outputs.version_changed == 'true'
|
||||
if: needs.detect-version-change.outputs.version_changed == 'true' && github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
72
docs/pipeline_executor_plan.md
Normal file
72
docs/pipeline_executor_plan.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# 🧩 Plan: `PipelineExecutor<TContext>`
|
||||
|
||||
## 🎯 Ziel
|
||||
Eine eigenständige, testbare Klasse zur Ausführung einer Middleware- und Handler-Pipeline, die:
|
||||
- Linear und sauber das `next()`-Verhalten abbildet
|
||||
- Typvalidierung durchführt (`isMiddleware`, `isHandler`)
|
||||
- Fehler behandelt und an konfigurierbare Handler weiterleitet
|
||||
- Optionale Hooks zur Tracing-Integration bietet (z. B. für Zeitmessung, Logging)
|
||||
- Am Ende eine dekorierte `Response` zurückliefert
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Schnittstelle (API)
|
||||
|
||||
```ts
|
||||
class PipelineExecutor<TContext extends IContext> {
|
||||
constructor(cfg: IHttpKernelConfig<TContext>);
|
||||
|
||||
run(
|
||||
ctx: TContext,
|
||||
middleware: Middleware<TContext>[],
|
||||
handler: Handler<TContext>,
|
||||
hooks?: IPipelineHooks<TContext>, // optional
|
||||
): Promise<Response>;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🪝 Hook-Schnittstelle (`IPipelineHooks`)
|
||||
|
||||
```ts
|
||||
interface IPipelineHooks<TContext> {
|
||||
onPipelineStart?(ctx: TContext): void;
|
||||
onStepStart?(name: string | undefined, ctx: TContext): void;
|
||||
onStepEnd?(name: string | undefined, ctx: TContext, duration: number): void;
|
||||
onPipelineEnd?(ctx: TContext, totalDuration: number): void;
|
||||
}
|
||||
```
|
||||
|
||||
- `name` ist `undefined`, wenn keine `.name` am Handler/Middleware gesetzt ist
|
||||
- Diese Hooks ermöglichen später Logging, Zeitmessung, Statistiken etc.
|
||||
- Der `TraceManager` wird dieses Interface implementieren
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Interne Aufgaben / Ablauf
|
||||
|
||||
1. `run(...)` beginnt mit Aufruf `onPipelineStart(ctx)`
|
||||
2. Zeitmessung (`performance.now()`)
|
||||
3. Dispatcher-Funktion führt jede Middleware mit `next()`-Kette aus
|
||||
4. Vor jedem Aufruf: `onStepStart(name, ctx)`
|
||||
5. Nach jedem Aufruf: `onStepEnd(name, ctx, duration)`
|
||||
6. Nach letztem Handler: `onPipelineEnd(ctx, totalDuration)`
|
||||
7. Ergebnis wird durch `cfg.decorateResponse(res, ctx)` geschickt
|
||||
8. Im Fehlerfall: `cfg.httpErrorHandlers[500](ctx, error)`
|
||||
|
||||
---
|
||||
|
||||
## ✅ Vorteile
|
||||
|
||||
- `HttpKernel` ist von Ausführungsdetails entkoppelt
|
||||
- Tracing-/Logging-System kann ohne Invasivität angeschlossen werden
|
||||
- Sehr gut testbar (z. B. Middleware-Mock + Hook-Aufrufe prüfen)
|
||||
- Erweiterbar für Timeout, Async-Context, Abbruchlogik etc.
|
||||
|
||||
---
|
||||
|
||||
## 📦 Dateiname-Vorschlag
|
||||
|
||||
- `src/Core/PipelineExecutor.ts` oder
|
||||
- `src/HttpKernel/PipelineExecutor.ts`
|
||||
33
src/Interfaces/IPipelineExecutorConfig.ts
Normal file
33
src/Interfaces/IPipelineExecutorConfig.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { ResponseDecorator } from '../Types/ResponseDecorator.ts';
|
||||
import { IContext } from './IContext.ts';
|
||||
import { IHttpErrorHandlers } from './IHttpErrorHandlers.ts';
|
||||
import { IPipelineHooks } from './IPipelineHooks.ts';
|
||||
|
||||
/**
|
||||
* Configuration object for the PipelineExecutor, defining how to handle
|
||||
* errors, responses, and tracing hooks.
|
||||
*
|
||||
* This allows the execution logic to remain decoupled from kernel-level behavior
|
||||
* while still supporting custom behavior injection.
|
||||
*
|
||||
* @template TContext - The context type propagated during pipeline execution.
|
||||
*/
|
||||
export interface IPipelineExecutorConfig<TContext extends IContext = IContext> {
|
||||
/**
|
||||
* Optional function used to transform or decorate the final Response object
|
||||
* before it is returned to the client.
|
||||
*/
|
||||
decorateResponse?: ResponseDecorator<TContext>;
|
||||
|
||||
/**
|
||||
* Optional map of error handlers, keyed by HTTP status codes (e.g., 404, 500).
|
||||
* These handlers are invoked if an error occurs during middleware or handler execution.
|
||||
*/
|
||||
errorHandlers?: IHttpErrorHandlers<TContext>;
|
||||
|
||||
/**
|
||||
* Optional hooks that allow tracing and lifecycle monitoring during pipeline execution.
|
||||
* Each hook is called at a specific phase of the middleware/handler lifecycle.
|
||||
*/
|
||||
pipelineHooks?: IPipelineHooks<TContext>;
|
||||
}
|
||||
36
src/Interfaces/IPipelineHooks.ts
Normal file
36
src/Interfaces/IPipelineHooks.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import {
|
||||
OnPipelineEnd,
|
||||
OnPipelineStart,
|
||||
OnStepEnd,
|
||||
OnStepStart,
|
||||
} from '../Types/mod.ts';
|
||||
import { IContext } from './IContext.ts';
|
||||
|
||||
/**
|
||||
* A set of optional hook functions that can be triggered during pipeline execution.
|
||||
* These hooks allow tracing, performance measurement, and logging to be integrated
|
||||
* without altering middleware or handler logic.
|
||||
*
|
||||
* @template TContext - The custom context type used within the application.
|
||||
*/
|
||||
export interface IPipelineHooks<TContext extends IContext = IContext> {
|
||||
/**
|
||||
* Triggered once before any middleware or handler is executed.
|
||||
*/
|
||||
onPipelineStart?: OnPipelineStart<TContext>;
|
||||
|
||||
/**
|
||||
* Triggered immediately before each middleware or handler runs.
|
||||
*/
|
||||
onStepStart?: OnStepStart<TContext>;
|
||||
|
||||
/**
|
||||
* Triggered immediately after each middleware or handler has finished executing.
|
||||
*/
|
||||
onStepEnd?: OnStepEnd<TContext>;
|
||||
|
||||
/**
|
||||
* Triggered after the entire pipeline completes execution.
|
||||
*/
|
||||
onPipelineEnd?: OnPipelineEnd<TContext>;
|
||||
}
|
||||
@@ -5,6 +5,8 @@ export type { IHttpErrorHandlers } from './IHttpErrorHandlers.ts';
|
||||
export type { IHttpKernel } from './IHttpKernel.ts';
|
||||
export type { IHttpKernelConfig } from './IHttpKernelConfig.ts';
|
||||
export type { IInternalRoute } from './IInternalRoute.ts';
|
||||
export type { IPipelineExecutorConfig } from './IPipelineExecutorConfig.ts';
|
||||
export type { IPipelineHooks } from './IPipelineHooks.ts';
|
||||
export type { IRouteBuilder, IRouteBuilderFactory } from './IRouteBuilder.ts';
|
||||
export {
|
||||
isDynamicRouteDefinition,
|
||||
|
||||
49
src/Types/PipelineHooks.ts
Normal file
49
src/Types/PipelineHooks.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { IContext } from '../Interfaces/mod.ts';
|
||||
|
||||
/**
|
||||
* A callback invoked when the middleware pipeline starts.
|
||||
*
|
||||
* @template TContext - The context type passed throughout the pipeline.
|
||||
* @param ctx - The context object for the current request.
|
||||
*/
|
||||
export type OnPipelineStart<TContext extends IContext> = (
|
||||
ctx: TContext,
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* A callback invoked immediately before a middleware or handler is executed.
|
||||
*
|
||||
* @template TContext - The context type passed throughout the pipeline.
|
||||
* @param name - Optional name of the current middleware or handler, if defined.
|
||||
* @param ctx - The context object for the current request.
|
||||
*/
|
||||
export type OnStepStart<TContext extends IContext> = (
|
||||
name: string | undefined,
|
||||
ctx: TContext,
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* A callback invoked immediately after a middleware or handler has completed.
|
||||
*
|
||||
* @template TContext - The context type passed throughout the pipeline.
|
||||
* @param name - Optional name of the current middleware or handler, if defined.
|
||||
* @param ctx - The context object for the current request.
|
||||
* @param duration - Execution time in milliseconds.
|
||||
*/
|
||||
export type OnStepEnd<TContext extends IContext> = (
|
||||
name: string | undefined,
|
||||
ctx: TContext,
|
||||
duration: number,
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* A callback invoked after the entire pipeline has completed execution.
|
||||
*
|
||||
* @template TContext - The context type passed throughout the pipeline.
|
||||
* @param ctx - The context object for the current request.
|
||||
* @param totalDuration - Total execution time of the pipeline in milliseconds.
|
||||
*/
|
||||
export type OnPipelineEnd<TContext extends IContext> = (
|
||||
ctx: TContext,
|
||||
totalDuration: number,
|
||||
) => void;
|
||||
@@ -39,6 +39,12 @@ export type { HttpStatusCode } from './HttpStatusCode.ts';
|
||||
export { isMiddleware } from './Middleware.ts';
|
||||
export type { Middleware } from './Middleware.ts';
|
||||
export type { Params } from './Params.ts';
|
||||
export type {
|
||||
OnPipelineEnd,
|
||||
OnPipelineStart,
|
||||
OnStepEnd,
|
||||
OnStepStart,
|
||||
} from './PipelineHooks.ts';
|
||||
export type { Query } from './Query.ts';
|
||||
export type { RegisterRoute } from './RegisterRoute.ts';
|
||||
export type { ResponseDecorator } from './ResponseDecorator.ts';
|
||||
|
||||
Reference in New Issue
Block a user