website refactor

This commit is contained in:
2026-01-13 00:16:14 +01:00
parent 5ea95eaf51
commit d18e2979ba
17 changed files with 1056 additions and 303 deletions

View File

@@ -0,0 +1,76 @@
/**
* Result type for operations that can fail
*
* Inspired by Rust's Result type, this provides a type-safe way to handle
* success and error cases without exceptions.
*/
export interface ResultOk<T> {
isOk(): true;
isErr(): false;
unwrap(): T;
unwrapOr(defaultValue: T): T;
getError(): never;
map<U>(fn: (value: T) => U): ResultOk<U>;
}
export interface ResultError<E> {
isOk(): false;
isErr(): true;
unwrap(): never;
unwrapOr(defaultValue: any): any;
getError(): E;
map<U>(fn: (value: any) => U): ResultError<E>;
}
export class Ok<T> implements ResultOk<T> {
constructor(private readonly value: T) {}
isOk(): true { return true; }
isErr(): false { return false; }
unwrap(): T { return this.value; }
unwrapOr(_defaultValue: T): T { return this.value; }
getError(): never {
throw new Error('Cannot get error from Ok result');
}
map<U>(fn: (value: T) => U): ResultOk<U> {
return new Ok(fn(this.value));
}
}
export class Err<E> implements ResultError<E> {
constructor(private readonly error: E) {}
isOk(): false { return false; }
isErr(): true { return true; }
unwrap(): never {
throw new Error(`Called unwrap on error: ${this.error}`);
}
unwrapOr(defaultValue: any): any { return defaultValue; }
getError(): E { return this.error; }
map<U>(_fn: (value: any) => U): ResultError<E> {
return this as any;
}
}
/**
* Result type alias
*/
export type Result<T, E> = ResultOk<T> | ResultError<E>;
/**
* Result class with static factory methods
*
* Usage:
* - Result.ok(value) creates a successful Result
* - Result.err(error) creates an error Result
*/
export const Result = {
ok<T>(value: T): Result<T, never> {
return new Ok(value);
},
err<E>(error: E): Result<never, E> {
return new Err(error);
},
};

View File

@@ -1,3 +1,5 @@
import { Result } from "../Result";
/**
* Mutation Contract
*
@@ -27,7 +29,7 @@ export interface Mutation<TInput = void, TOutput = void> {
* Execute the mutation
*
* @param input - Mutation input
* @returns Output (optional)
* @returns Result indicating success or error
*/
execute(input: TInput): Promise<TOutput>;
execute(input: TInput): Promise<Result<TOutput, string>>;
}

View File

@@ -1,5 +1,4 @@
import { PageQueryResult } from "./PageQueryResult";
import { Result } from "../Result";
/**
* PageQuery contract interface
@@ -10,18 +9,18 @@ import { PageQueryResult } from "./PageQueryResult";
* - Server-side composition classes
* - Call services that call apps/api
* - Assemble a Page DTO
* - Return explicit result describing route outcome
* - Explicit result describing route outcome
* - Do not implement business rules
*
* @template TPageDto - The Page DTO type this query produces
* @template TApiDto - The API DTO type this query produces
* @template TParams - The parameters required to execute this query
*/
export interface PageQuery<TPageDto, TParams = void> {
export interface PageQuery<TApiDto, TParams = void> {
/**
* Execute the page query
*
* @param params - Parameters required for query execution
* @returns Promise resolving to a PageQueryResult discriminated union
* @returns Promise resolving to a Result
*/
execute(params: TParams): Promise<PageQueryResult<TPageDto>>;
}
execute(params: TParams): Promise<Result<TApiDto, string>>;
}